Compare commits

...

1617 Commits

Author SHA1 Message Date
Sagar Sharma
f064368dbd Revert "fix: reference error while using exchange rate revaluation" 2023-06-15 11:44:55 +05:30
Sagar Sharma
ccdf2e6340 Merge pull request #35700 from s-aga-r/FIX-SR-DIFF-QTY
fix: update `Stock Reconciliation` diff qty while reposting
2023-06-15 11:42:24 +05:30
s-aga-r
6a1b0a2fab fix: update Stock Reconciliation diff qty while reposting 2023-06-15 11:39:22 +05:30
ruthra kumar
be78ae72ef Merge pull request #35694 from ruthra-kumar/reference_error_on_err
fix: reference error while using exchange rate revaluation
2023-06-14 20:44:16 +05:30
ruthra kumar
cd538e138a fix: reference error while using exchange rate revaluation 2023-06-14 20:28:28 +05:30
rohitwaghchaure
4820221a41 Merge pull request #35636 from s-aga-r/FIX-SBB-AttributeError
fix: miscellaneous
2023-06-14 16:02:04 +05:30
Suraj Shetty
afaa85fbde fix(telephony): Check if setup_phone method exists
We are just overriding Data control. 

This fails if other field type like "Small Text" has option set as "Phone"
2023-06-14 15:54:27 +05:30
s-aga-r
7549a5c371 fix(ux): add filters for SBB 2023-06-14 15:04:51 +05:30
s-aga-r
5c805db573 fix(ux): add is_cancelled=0 filter for SBB 2023-06-14 15:04:51 +05:30
s-aga-r
fe054508f1 fix: 'NoneType' object has no attribute 'precision' for Job Card 2023-06-14 15:04:36 +05:30
Deepesh Garg
984f89d274 fix: Validation for delivery date in Sales Order (#35597)
* fix: Validation for delivery date in Sales Order

* chore: update utils

* chore: revert

* chore: Add default delivery date
2023-06-13 21:35:52 +05:30
Deepesh Garg
937c0feefe fix: Lower deduction certificate not getting applied (#35667) 2023-06-13 20:06:36 +05:30
Anand Baburajan
491a50a027 fix: make showing taxes as table in print configurable (#35672) 2023-06-13 19:42:56 +05:30
Hossein Yousefian
9f669d4c2f Stock aging report fix when called in dashboard chart (#35671)
fix: get_range_age conditions fixed

see https://github.com/frappe/erpnext/issues/35669
2023-06-13 19:20:07 +05:30
Devin Slauenwhite
20de27d480 fix(accounts): validate payment entry references with latest data. (#31166)
* test: payment entry over allocation.

* fix: validate allocated_amount against latest outstanding amount.

* fix: payment entry get outstanding documents for advance payments

* fix: only fetch latest outstanding_amount.

* fix: throw if reference is allocated

* test: throw error if a reference has been partially allocated after inital creation.

* chore: test name

* fix: remove unused part of test

* chore: linter

* chore: more user friendly error messages

* fix: only validate outstanding amount if partly paid and don't filter by cost center

* chore: minor refactor for doc.cost_center

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>

---------

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-06-13 19:06:53 +05:30
Ankush Menat
a3ea985348 refactor: Use db.set_single_value (#35668)
I just applied semgrep autofix. Untested completed, review before merging.

```yaml
- id: frappe-set-value-semantics
  patterns:
    - pattern-either:
      - pattern: frappe.db.set_value($DOCTYPE, None, $...AFTER)
      - pattern: frappe.db.set_value($DOCTYPE, $DOCTYPE, $...AFTER)
  fix: frappe.db.set_single_value($DOCTYPE, $...AFTER)
  message: |
    If $DOCTYPE is a single doctype then using `frappe.db.set_value` is discouraged for setting values in DB. Use db.set_single_value for single doctype instead.
  languages: [python]
  severity: ERROR
```
2023-06-13 17:30:38 +05:30
ruthra kumar
b43e068852 Merge pull request #35659 from ruthra-kumar/fix_attribute_error_in_payment_reconciliation
fix: attribute error on payment reconciliation tool
2023-06-13 10:16:26 +05:30
ruthra kumar
b672616617 Merge pull request #35620 from ruthra-kumar/err_higher_allowance_for_debit_credit_diff
fix: allow custom rounding loss allowance in Exchange Rate Revaluation
2023-06-13 09:46:08 +05:30
ruthra kumar
bada5796fa fix: attribute error on payment reconciliation tool 2023-06-13 09:32:24 +05:30
rohitwaghchaure
4ee08b92ae Merge pull request #35629 from rohitwaghchaure/fixed-process-loss-in-job-card
fix: added process loss in job card
2023-06-12 23:29:15 +05:30
ruthra kumar
96a0132501 fix: allow user to set rounding loss allowance for accounts balance 2023-06-12 22:05:08 +05:30
Ankush Menat
f957a84830 build!: update deps and drop setup.py (#35653) 2023-06-12 21:46:06 +05:30
rohitwaghchaure
64586187de Merge branch 'develop' into fixed-process-loss-in-job-card 2023-06-12 21:39:29 +05:30
rohitwaghchaure
62011410b2 fix: test case PyPDF2 (#35652)
fix: test case
2023-06-12 19:22:55 +05:30
Ankush Menat
1e8ee9354a fix(DX): Check Frappe and ERPNext major versions (#35651) 2023-06-12 19:20:52 +05:30
rohitwaghchaure
93fe923e2a Merge branch 'develop' into fixed-process-loss-in-job-card 2023-06-12 19:04:19 +05:30
mergify[bot]
4f3d531f35 fix: don't set default payment amount in case of invoice return (backport #35645) (#35647)
fix: don't set default payment amount in case of invoice return (#35645)

(cherry picked from commit 79483cc90e)

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
2023-06-12 18:43:26 +05:30
Sagar Sharma
f1e902be5c Merge pull request #35646 from s-aga-r/FIX-ISS-23-24-01138-1
fix: Stock Reconciliation document update while reposting
2023-06-12 18:42:34 +05:30
s-aga-r
db159dd11f fix: Stock Reconciliation document update while reposting 2023-06-12 18:28:16 +05:30
Rohit Waghchaure
0382eecff4 fix: test case 2023-06-12 18:20:38 +05:30
ruthra kumar
42f4f80e0c fix: Payment against credit notes will be considered as payment against parent invoice in Accounts Receivable/Payable report (#35642)
* fix: payment against credit note should be linked to parent invoice

* test: AR/AP report for payment against cr note scenario

* fix: cr_note shows up as outstanding invoice

Payment made against cr_note causes it be reported as outstanding invoice
2023-06-12 17:35:13 +05:30
Deepesh Garg
2f24546b21 fix: Make difference entry button not working (#35622) 2023-06-12 15:20:28 +05:30
s-aga-r
c9923e4996 fix: 'NoneType' object has no attribute 'precision' 2023-06-12 12:33:13 +05:30
s-aga-r
c6acb0d200 fix: DocType not found 2023-06-12 12:33:13 +05:30
s-aga-r
0b009da122 fix(ux): only list related DocTypes 2023-06-12 12:33:13 +05:30
s-aga-r
9a12545ac3 fix(ux): add filter disabled=0 for batch no 2023-06-12 12:33:07 +05:30
David Arnold
c1b42b858d fix: set Phone and Email option in doctypes (#35549) 2023-06-11 19:34:41 +05:30
ruthra kumar
dcbd7d5f1f fix: incorrect TCS amount while customer has advance payment (#35397)
* fix: incorrect TCS amount while customer has advance payment

* test: only unallocated advance should for threshold breach validation
2023-06-10 20:55:30 +05:30
Rohit Waghchaure
e9a6191af9 fix: added process loss in job card 2023-06-09 20:33:46 +05:30
Sagar Sharma
e3802d1c3f Merge pull request #35618 from s-aga-r/FIX-SBB-SERIAL-NO-QTY
fix: reset entries qty to `1` for serial item
2023-06-09 13:01:01 +05:30
Anand Baburajan
7bd369c49b fix: calculate wdv depr schedule properly for existing assets [dev] (#35614)
* fix: calculate wdv depr schedule properly for existing assets

* fix: calculate wdv depr schedule properly for existing assets properly

* chore: properly call _get_pro_rata_amt
2023-06-09 12:53:10 +05:30
s-aga-r
b5c5a90f71 fix(ux): set warehouse for new row 2023-06-09 12:22:24 +05:30
s-aga-r
1f28ca717e fix(ux): set entries qty to 1 before making the field read-only 2023-06-09 12:06:46 +05:30
s-aga-r
1d904c0a86 fix(ux): make qty field read-only for serial item 2023-06-09 12:05:02 +05:30
Sagar Sharma
9a819103a7 Merge pull request #35617 from s-aga-r/FIX-CBAL-TypeError
fix: `TypeError` in Closing Stock Balance
2023-06-09 11:36:20 +05:30
s-aga-r
93e3fe8445 fix: reset entries qty to 1 for serial item 2023-06-09 11:10:47 +05:30
s-aga-r
446253ff39 fix: TypeError in Closing Stock Balance 2023-06-09 09:30:24 +05:30
Christian Werner
65b2e1fc33 fix: set parent_project when creating a new timesheet (#35607)
fix "When Creating a new Timesheet from an Task - parent_project is empty" #35578
2023-06-08 20:00:40 +05:30
Raffael Meyer
b91bb17779 refactor: get default contact or address (#35248)
* refactor: get_party_shipping_address

* refactor: get_default_contact

* chore: adding docstrings

* fix: keep original order

* fix: use get_all instead of get_list

---------

Co-authored-by: ruthra kumar <ruthra@erpnext.com>
2023-06-08 19:49:09 +05:30
ruthra kumar
9cd982aa54 Merge pull request #35610 from ruthra-kumar/fix_travis
chore: fix travis
2023-06-08 15:53:50 +05:30
ruthra kumar
992d61bd90 chore: fix travis 2023-06-08 15:11:46 +05:30
Didiman1998
0c12d4d3c5 fix: remove code that causes upscrolling (#35140)
Co-authored-by: Dietmar Fischer <fischer@kk-software.de>
2023-06-07 22:35:44 +05:30
Trusted Computer
781548e46e Fix: CSS not applied to product title (#35582)
In an erpnext website, the /all-products route shows website items that have been published to the web site.

In the list view (erpnext/e_commerce/product_ui/list.js), the css class is null for the product title. Instead, inline style statements have been added in that can not be modified by overriding CSS.

This fix uses a similar approach to that which is taken in the grid view (erpnext/e_commerce/product_ui/grid.js). It removes the null CSS parameter in the product title link as well as the inline style statement. Then, as in the grid view, the product title is wrapped in a div tag with the product_title CSS class.

This makes it possible to style the product title as desired with a CSS override.

Closes #35580
2023-06-07 22:11:49 +05:30
Deepesh Garg
f732cac678 fix: Project in item-wise sales register (#35596) 2023-06-07 22:06:05 +05:30
Raffael Meyer
0dde4d4c69 refactor: use delete_contact_and_address (#34497)
Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-06-07 22:02:38 +05:30
Dirk van der Laarse
3b409af9a0 fix: exclude disabled customers when fetching customers on process statement of accounts (#35539)
fix: exclude disabled when fetching customers
2023-06-07 22:01:44 +05:30
Raffael Meyer
e9d7b9f0f4 fix: column formatting in Bank Reconciliation Tool (#35540)
* fix(Bank Reconciliation): format Date column

* fix(Bank Reconciliation): format Party column

* fix(Bank Reconciliation): actions button

- wrong closing tag
- explicitly quote data-name

* fix(Bank Reco): format date and link in dialog
2023-06-07 21:51:49 +05:30
Raffael Meyer
e1f3b7cbc8 fix: pass translated label to change button type (#35564)
fix: change button type for translated labels

Co-authored-by: Marica <maricadsouza221197@gmail.com>
2023-06-07 21:49:02 +05:30
HarryPaulo
a9a47a51e4 fix: based on status_update.py update opportunity status to converted… (#35145)
fix: based on status_update.py update opportunity status to converted on sales submit
2023-06-07 21:35:52 +05:30
Deepesh Garg
0108b1abe2 fix: Improve validation message (#35489)
* fix: Improve validation message

* Update erpnext/selling/doctype/customer/customer.py

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>

---------

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2023-06-07 21:33:36 +05:30
Ankush Menat
0166f69b31 chore: extend default role profiles 2023-06-07 15:09:49 +05:30
rohitwaghchaure
930a107af8 Merge pull request #35567 from s-aga-r/FIX-SBB-STATUS
fix(ux): serial and batch bundle status
2023-06-07 14:49:43 +05:30
Ankush Menat
4507cb3cd7 fix: enqueue_after_commit wherever it makes sense (#35588) 2023-06-07 11:58:36 +05:30
Deepesh Garg
76197cc437 chore: Default role profiles (#35584) 2023-06-07 10:11:32 +05:30
Deepesh Garg
2ffcca6f10 fix: Interest Accrual on Loan Topup (#35555)
* fix: Interest Accrual on Loan Topup

* chore: CI

* chore: Ignore test
2023-06-07 10:06:13 +05:30
Nabin Hait
1cf1c7943f Merge pull request #35572 from nabinhait/quotation-fix
feat: ability to create quotation against a prospect
2023-06-06 21:54:24 +05:30
Sagar Sharma
a14a08dcb4 Merge pull request #35569 from s-aga-r/FIX-SO-SR-TEST
fix(test): `test_stock_reservation_against_sales_order`
2023-06-06 16:13:22 +05:30
Nabin Hait
5a0aacc0b6 fix: get party details 2023-06-06 15:39:22 +05:30
Nabin Hait
47ce6de57d feat: ability to create quotation against a prospect 2023-06-06 15:19:04 +05:30
s-aga-r
8fe1904f3f fix(test): test_stock_reservation_against_sales_order 2023-06-06 14:59:17 +05:30
s-aga-r
d6208d2e45 fix(ux): serial and batch bundle status 2023-06-06 12:07:46 +05:30
rohitwaghchaure
9e650a004a Merge pull request #35562 from rohitwaghchaure/fixed-validation-for-stock-entry
fix: added validation for insufficient stock during stock transfer
2023-06-05 19:42:03 +05:30
Rohit Waghchaure
dcb0462d51 fix: added validation for insufficient stock during stock transfer 2023-06-05 16:58:54 +05:30
Smit Vora
b1ef19a0cd fix(regional): allow regional override for updating gl_dict (#35550) 2023-06-05 01:43:26 +05:30
rohitwaghchaure
64f767b95d Merge pull request #35552 from rohitwaghchaure/fixed-serial-batch-get-query
fix: get_query for batch number and incorrect batch qty
2023-06-04 16:56:46 +05:30
Rohit Waghchaure
acd12c5830 fix: get_query for batch number and incorrect batch qty 2023-06-04 16:09:01 +05:30
Sagar Sharma
5ebf46a1b5 Merge pull request #35510 from s-aga-r/FIX-ISS-23-24-01141
fix: ignore `Non-Stock Item` while calculating `% Picked` in Sales Order
2023-06-03 11:18:05 +05:30
rohitwaghchaure
14292ffc6f Merge pull request #34564 from rohitwaghchaure/serial-no-normalization
Feat: Serial No Normalization and Serial Batch Bundle
2023-06-02 18:13:02 +05:30
Deepesh Garg
abc6fe0b06 refactor!: Remove custom cashflow report mapper (#35523)
* refactor: Remove custom cashflow mapper

* chore: patch to delete docs

* fix: Cleanup defaults during install

* fix: Remove custom cashflow mapper from consolidated financial statement
2023-06-02 17:48:59 +05:30
Rohit Waghchaure
bb95451db6 feat: added jinja method get_serial_or_batch_nos for print format and new print format 'Purchase Receipt Serial and Batch Bundle Print for reference 2023-06-02 17:14:18 +05:30
Rohit Waghchaure
40ab3bdd35 test: test cases for serial and batch bundle 2023-06-02 17:14:18 +05:30
Rohit Waghchaure
42b229435c fix: stock reco test case for serial and batch bundle 2023-06-02 17:14:18 +05:30
Rohit Waghchaure
f4cfc589c6 fix: serial and batch selector 2023-06-02 17:14:18 +05:30
Rohit Waghchaure
39da92929b fix: serial and batch selector 2023-06-02 17:14:18 +05:30
Rohit Waghchaure
26b39ac7f4 fix: travis for asset capitalization and asset repair 2023-06-02 17:14:18 +05:30
Rohit Waghchaure
e88c5d6d90 fix: travis for subcontracting module 2023-06-02 17:14:18 +05:30
Rohit Waghchaure
f79f2a3bab fix: dialog issue 2023-06-02 17:14:18 +05:30
Rohit Waghchaure
74ab20f97a fix: travis for POS merge invoice and putaway rule 2023-06-02 17:14:18 +05:30
Rohit Waghchaure
f8bf4aa7c8 fix: travis for work order, pos invoice and landed cost voucher 2023-06-02 17:14:17 +05:30
Rohit Waghchaure
48fbf99e6d fix: travis for sales and purchase invoice 2023-06-02 17:14:17 +05:30
Rohit Waghchaure
d3ceb07936 fix: travis 2023-06-02 17:14:17 +05:30
Rohit Waghchaure
f704eb7581 fix: average batch wise valuation 2023-06-02 17:14:17 +05:30
Rohit Waghchaure
854b89f252 fix: batch valuation for old entries 2023-06-02 17:14:17 +05:30
Rohit Waghchaure
c2d7461d3c fix: travis issue 2023-06-02 17:14:17 +05:30
Rohit Waghchaure
7290dd87be fix: linters and travis 2023-06-02 17:14:16 +05:30
Rohit Waghchaure
9b72845f0f feat: serial and batch bundle for pick list 2023-06-02 17:14:16 +05:30
Rohit Waghchaure
648efca940 feat: auto create serial and batch bundle 2023-06-02 17:14:16 +05:30
Rohit Waghchaure
c1132d1e6d fix: serial and batch selector and added deprecated decorator 2023-06-02 17:14:16 +05:30
Rohit Waghchaure
440510337c fix: travis 2023-06-02 17:14:16 +05:30
Rohit Waghchaure
0eaf6de5de feat: serial and batch bundle for POS 2023-06-02 17:14:16 +05:30
Rohit Waghchaure
467046436b refactor: serial no ledger and batchwise balance history report 2023-06-02 17:14:16 +05:30
Rohit Waghchaure
ba6e1447ef refactor: serial and batch bundle for Maintenance Schedule 2023-06-02 17:14:16 +05:30
Rohit Waghchaure
e50e5cc7b1 feat: serial and batch bundle for GIT stock entry 2023-06-02 17:14:15 +05:30
Rohit Waghchaure
5bb3173676 refactor: rename doctype serial and batch ledger to serial and batch entry 2023-06-02 17:14:15 +05:30
Rohit Waghchaure
16f26fb3d8 refactor: serial and batch package creation for finished item and cleanup code 2023-06-02 17:14:15 +05:30
Rohit Waghchaure
86da306cca feat: added negative inventory validation and restrict to make backdated entry for serial nos 2023-06-02 17:14:15 +05:30
Rohit Waghchaure
674bd3e2e5 feat: serial and batch bundle for Packing Items 2023-06-02 17:14:15 +05:30
Rohit Waghchaure
9c097e85f8 feat: serial and batch bundle for Stock Reconciliation 2023-06-02 17:14:14 +05:30
Rohit Waghchaure
5ddd55a8ae feat: serial and batch bundle for Subcontracting 2023-06-02 17:14:14 +05:30
Rohit Waghchaure
e6143abb8a refactor: added new file serial batch bundle 2023-06-02 17:14:14 +05:30
Rohit Waghchaure
f1b5966680 refactor: serial and batch reposting 2023-06-02 17:14:14 +05:30
Rohit Waghchaure
6c9b212dd1 fix: removed sales and purchase fields from serial nos 2023-06-02 17:14:14 +05:30
Rohit Waghchaure
ba1aac1613 chore: used frappe.db.bulk_insert to create serial nos and serial bunndle 2023-06-02 17:14:14 +05:30
Rohit Waghchaure
bc75a7ef44 refactor: serial no normalization 2023-06-02 17:14:14 +05:30
Nabin Hait
f11d9b019d fix: Ignore permissions while submitting account closing balance record (#35536) 2023-06-02 16:57:00 +05:30
Suraj Shetty
e75bd72fe4 Merge pull request #35530 from surajshetty3416/fix-task-gantt 2023-06-02 11:09:06 +05:30
Suraj Shetty
f7b2d103e7 fix: Task gantt popup style 2023-06-02 10:55:29 +05:30
Sagar Sharma
13f427a762 Merge pull request #35529 from frappe/mergify/bp/develop/pr-35481
fix: update `Stock Reconciliation` document while reposting (backport #35481)
2023-06-01 22:01:10 +05:30
s-aga-r
0fa56bcdce test: add test case for update stock reconciliation doc
(cherry picked from commit 5c9506c8ca)
2023-06-01 15:55:28 +00:00
s-aga-r
88a3f65d3d fix: update Stock Reconciliation document while reposting
(cherry picked from commit cc95cedfee)
2023-06-01 15:55:28 +00:00
Sagar Sharma
ebf03a51f3 Merge pull request #35525 from s-aga-r/FIX-STOCK-RESERVATION-TEST-CASE
fix(test): `test_stock_reservation_against_sales_order`
2023-06-01 19:41:12 +05:30
rohitwaghchaure
fe6a0a6c30 Merge pull request #35498 from rohitwaghchaure/fixed-db-binlogs-getting-full
fix: old data reposting causing low server disk space
2023-06-01 19:28:03 +05:30
s-aga-r
4044c2ed40 fix(test): test_stock_reservation_against_sales_order 2023-06-01 17:00:57 +05:30
brunoherrick
4eb2717c3b feat(accounts): add Portuguese SNC CoA (#35486)
The ultimate goal of this commit is to add an updated Portuguese Chart of Accounts (CoA), based on Portugal's SNC norm. Account numbers are included. "Account types" shall ideally be confirmed and improved by an accountant. Howbeit, the account types are mostly inspired on former OpenERP, now designated Odoo.
2023-06-01 15:38:18 +05:30
ruthra kumar
c02fc955c5 Merge pull request #35518 from ruthra-kumar/add_precision_in_exchange_rate_revaluation
fix:higher precision causes ERR to misjudge zero bal acc as non-zero
2023-06-01 14:59:04 +05:30
ruthra kumar
0319650187 Merge pull request #35112 from ruthra-kumar/gp_report_simplify_groupby_invoice
refactor(Gross Profit): simplify group by invoice logic
2023-06-01 14:34:01 +05:30
ruthra kumar
0cd47f07a6 fix: higher precision makes ERR to misjudge zero bal acc as non-zero 2023-06-01 14:24:03 +05:30
s-aga-r
0305a925fe fix: ignore Non-Stock Item while calculating % Picked in Sales Order 2023-06-01 14:18:48 +05:30
s-aga-r
03d7742737 fix: ignore Non-Stock Item mapping in Pick List 2023-06-01 14:18:39 +05:30
Akshay
e08d6fb2cb chore: typo in pricing rule schema (#35457) 2023-06-01 14:16:52 +05:30
Rohit Waghchaure
fb1a40cada fix: old data reposting causing low server disk space 2023-05-31 18:20:56 +05:30
rohitwaghchaure
cb19ebcd85 Merge pull request #35482 from rohitwaghchaure/fixed-stock-entry-missing-bom-details
fix: missing bom details in the stock entry
2023-05-31 17:29:19 +05:30
Ankush Menat
4bdd276f74 Merge pull request #35409 from nabinhait/workspace-cleanup
refactor: Workspace cleanup
2023-05-31 16:40:26 +05:30
Sagar Sharma
a250562f0b Merge pull request #35503 from s-aga-r/FIX-ISS-23-24-01158
fix(ux): throw if no row selected to create repost entries
2023-05-31 16:35:41 +05:30
Sagar Sharma
fe7c626098 Merge branch 'develop' into FIX-ISS-23-24-01158 2023-05-31 16:34:00 +05:30
Ankush Menat
bb67cc03df chore: typo 2023-05-31 16:31:58 +05:30
s-aga-r
1905239ec2 fix(ux): throw if no row selected to create repost entries 2023-05-31 15:30:45 +05:30
Sagar Vora
1287ee65b5 Merge pull request #35500 from resilient-tech/remove-wl 2023-05-31 14:44:59 +05:30
Sagar Vora
517d8a03ec chore: remove whitelisting for method not accessed from UI 2023-05-31 14:39:03 +05:30
Ankush Menat
686685bba0 fix: use kwargs in new_doc (#35497)
To handle https://github.com/frappe/frappe/pull/21190#event-9386089620
2023-05-31 12:50:14 +05:30
Deepesh Garg
bb21c044f6 fix: Billing Address display in buying transactions (#35451) 2023-05-31 11:02:30 +05:30
Deepesh Garg
27d5e6a99b fix: Error while validating budget (#35487)
* fix: Error while validating budget

* chore: remove print statement
2023-05-31 10:51:33 +05:30
Rohit Waghchaure
2fc7d82324 fix: missing bom details in the stock entry 2023-05-30 18:22:48 +05:30
rohitwaghchaure
ffd5308ed9 Merge pull request #35478 from rohitwaghchaure/fixed-lead-time-calculation-in-work-order
fix: incorrect transferred qty in the job card
2023-05-30 18:11:57 +05:30
Rohit Waghchaure
d3a5e49db9 fix: incorrect transfer quantity in the job card 2023-05-30 17:27:16 +05:30
Anand Baburajan
dbdc420066 fix: allow assets with depr entries to be cancelled (#35477)
fix: allow asset with depr entries to be cancelled
2023-05-30 16:28:57 +05:30
Nabin Hait
e78a7de1e5 fix: Rearranged accounting module links 2023-05-30 13:25:00 +05:30
Nabin Hait
5cf4c8c8b7 fix: removed duplicate links of manufacturing workspace 2023-05-30 13:18:58 +05:30
Nabin Hait
86f88817a9 fix: Added pos links in Selling workspace 2023-05-30 13:18:58 +05:30
Nabin Hait
0b28f641ad fix: Delete Retail and Utilities worspaces amd hide default Settings and Integration workspaces 2023-05-30 13:18:52 +05:30
Nabin Hait
243c49c550 refactor: Workspace cleanup 2023-05-30 13:17:59 +05:30
Sagar Sharma
7a3d16fc61 Merge pull request #35459 from marc-dll/FIX_retention_stock_entry_conversion_factor
fix: retention stock entry: grab conversion factor from source
2023-05-30 11:05:58 +05:30
Sagar Sharma
91ca266db6 Merge branch 'develop' into FIX_retention_stock_entry_conversion_factor 2023-05-30 11:05:37 +05:30
rohitwaghchaure
df921b79a4 Merge pull request #35465 from rohitwaghchaure/fixed-inter-transfer-company
fix: rate not fetching properly for inter transfer purchase order
2023-05-30 09:14:16 +05:30
Rohit Waghchaure
2931c657f4 fix: rate not fetching properly for inter transfer purchase order 2023-05-30 08:34:12 +05:30
rohitwaghchaure
7dce06021e Merge pull request #35462 from ankush/item_quick_entry
refactor!: Drop custom item quick entry
2023-05-30 08:32:09 +05:30
Sagar Sharma
ed0c8ae452 Merge branch 'develop' into FIX_retention_stock_entry_conversion_factor 2023-05-30 08:05:54 +05:30
Anand Baburajan
ae26d72f7f fix: monthly wdv depr schedule for existing assets [dev] (#35460)
fix: monthly wdv depr schedule for existing assets
2023-05-29 23:18:07 +05:30
Ankush Menat
b10e19141c refactor!: Drop item quick entry
- Item variants creator - we have better one on document
- Everything else - hardcoded behaviour that's not needed anymore IMO.
2023-05-29 22:33:56 +05:30
Marc de Lima Lucio
6954f538c9 fix: retention stock entry: grab conversion factor from source 2023-05-29 17:41:14 +02:00
Ankush Menat
d84c8de46c Merge pull request #35453 from ankush/stock_onboarding_workspace
fix: stock onboarding
2023-05-29 15:13:14 +05:30
Ankush Menat
964bb1d948 chore: docs for stock settings
[skip ci]
2023-05-29 15:11:28 +05:30
Ankush Menat
8fe8f80033 fix: replace stock projected with ledger
Ledger is much more widely used report, better to show that first?
2023-05-29 14:44:54 +05:30
Ankush Menat
dd245ccc7f fix: reorder stock reco tour 2023-05-29 14:44:54 +05:30
Ankush Menat
3341cd6b80 fix: filter parent warehouses by company 2023-05-29 14:44:54 +05:30
Ankush Menat
aa9f926298 fix: warehouse tour
- remove warehouse type, it doesn't do what it says. Misleading.
2023-05-29 14:44:54 +05:30
Ankush Menat
81e901ba62 fix: disable/enable with button 2023-05-29 14:44:54 +05:30
Ankush Menat
40ce33dff1 fix: warehouse form cleanup
- organize fields
- group transit fields and move them lower
- enable/disable should be button
- hide pointless fields from listview
2023-05-29 14:44:54 +05:30
Ankush Menat
7a18db561f fix: hide ledger button on new warehouse 2023-05-29 14:44:54 +05:30
Ankush Menat
2e13fbab5e fix: stock settings tour
- remove dead fields
- Keep only essential fields in tour
2023-05-29 14:44:50 +05:30
HarryPaulo
b7407a1d81 feat: add todo calendar to bootinfo.calendars (#35124)
* feat: add todo calendar to bootinfo.calendars

* chore: Linting Issues

---------

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-05-29 10:37:35 +05:30
Raffael Meyer
1f08330ae1 fix: labels and translations (#34896)
* fix: german translation of expense claim

* fix: consistent labels and translations in project Costing and Billing

* fix: german translation of Stock Entry

---------

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-05-29 09:56:16 +05:30
Akshay
1ab04344db fix (ui): debit note issued status indicator color (#35401)
* fix: debit note issued status indicator color

* fix: change DebitNoteIssued color from grey to gray
2023-05-29 09:42:01 +05:30
Vishnu VS
01567b5ec4 fix(UX): task and project name in error message (#35435) 2023-05-29 09:39:13 +05:30
Nabin Hait
3504bf7f62 fix: Show future payments in accounts receivable summary (#35416) 2023-05-29 09:23:40 +05:30
Sagar Sharma
afd9098612 Merge pull request #35437 from s-aga-r/FIX-ISS-23-24-01015
fix: incorrect `POS Reserved Qty` in `Stock Projected Qty` Report
2023-05-28 15:04:47 +05:30
Sagar Sharma
336ff5b327 Merge branch 'develop' into FIX-ISS-23-24-01015 2023-05-27 12:13:39 +05:30
Sagar Sharma
027de41600 fix: incorrect POS Reserved Qty in Stock Projected Qty Report 2023-05-27 12:05:37 +05:30
rohitwaghchaure
4099330bf4 Merge pull request #35426 from rohitwaghchaure/fixed-incorrect-actual-qty-bin
fix: incorrect available quantity in BIN
2023-05-26 22:47:42 +05:30
Sagar Sharma
c3fa1f7450 Merge pull request #34805 from s-aga-r/stock-reservation
feat: Stock Reservation against Sales Order
2023-05-26 17:13:44 +05:30
Sagar Sharma
8cc8af8204 Merge branch 'develop' into stock-reservation 2023-05-26 15:28:54 +05:30
Rohit Waghchaure
718ad3f240 fix: travis 2023-05-26 11:29:22 +05:30
Sagar Sharma
761f8a9f05 fix: use float_precision while checking for negative stock in BIN 2023-05-26 04:23:36 +05:30
Rohit Waghchaure
9e5e2de5d5 fix: incorrect available quantity in BIN 2023-05-25 23:56:23 +05:30
Sagar Sharma
781c93c0e6 Merge pull request #35108 from s-aga-r/PACKING-SLIP-FOR-DN-PACKED-ITEMS
refactor: Packing Slip
2023-05-25 23:54:04 +05:30
Sagar Sharma
b4362e5517 Merge branch 'develop' into PACKING-SLIP-FOR-DN-PACKED-ITEMS 2023-05-25 23:15:46 +05:30
mergify[bot]
55806c51f2 fix: Gross and Net Profit Report - incorrect calculation of totals
* fix: account group totals calculation to consider include_in_gross

(cherry picked from commit 8dcb9302b4)

* refactor: remove unused parameters

(cherry picked from commit 50822f207e)

* refactor: merge separate loops for calculating group / leaf node totals
rename function
remove return statement as the list is  mutated

(cherry picked from commit 1a3b9c5bdf)

* fix: add total col for gross and net profit

(cherry picked from commit cb9b4fbb91)

---------

Co-authored-by: Anoop Kurungadam <anoop@earthianslive.com>
2023-05-25 18:12:50 +05:30
Sagar Sharma
6f0867b006 Merge branch 'develop' into PACKING-SLIP-FOR-DN-PACKED-ITEMS 2023-05-25 18:04:06 +05:30
Sagar Sharma
196e18187f fix(patch): add patch to set packed_qty in draft DN 2023-05-25 18:03:39 +05:30
Sagar Sharma
ba59f53939 Merge pull request #35422 from s-aga-r/stock-balance-typo
chore: typo in stock balance
2023-05-25 17:22:13 +05:30
Sagar Sharma
5c7f3adf5a Merge branch 'develop' into stock-balance-typo 2023-05-25 16:04:11 +05:30
Sagar Sharma
c4e1f927ee chore: typo in stock balance 2023-05-25 16:03:15 +05:30
Sagar Sharma
82f0bd9ee9 feat: add Reserved Stock column in Stock Balance Report 2023-05-25 15:57:06 +05:30
Sagar Sharma
988db2eaf6 Merge branch 'develop' into stock-reservation 2023-05-25 15:10:54 +05:30
ruthra kumar
ec5d34117b Merge pull request #35417 from ruthra-kumar/fix_ambiguous_company_in_gross_profit_report
fix(Gross Profit): 'company' column is ambiguous in filter
2023-05-25 15:06:35 +05:30
Sagar Sharma
ccb2dc4df5 Merge branch 'develop' into stock-reservation 2023-05-25 14:35:59 +05:30
ruthra kumar
448712f719 fix(Gross Profit): 'company' column is ambiguous in filter 2023-05-25 14:18:41 +05:30
Sagar Sharma
fefd788eb5 fix(ux): add non-group warehouse filter 2023-05-25 11:49:47 +05:30
rohitwaghchaure
0bc9c3260e Merge pull request #35348 from rohitwaghchaure/refactor-stock-balance-report
refactor: stock balance report
2023-05-24 19:46:04 +05:30
rohitwaghchaure
693133d8f7 Merge pull request #35410 from rohitwaghchaure/fixed-negative-reserved-qty-for-production-plan
fix: Negative value in Reserved Qty for Production Plan
2023-05-24 19:08:14 +05:30
Rohit Waghchaure
a37608a36c fix: Negative value in Reserved Qty for Production Plan 2023-05-24 17:14:00 +05:30
Sagar Sharma
2813042936 Merge branch 'develop' into PACKING-SLIP-FOR-DN-PACKED-ITEMS 2023-05-24 14:35:51 +05:30
rohitwaghchaure
565322daba Merge branch 'develop' into stock-reservation 2023-05-24 14:32:04 +05:30
rohitwaghchaure
0d8f48891d Merge pull request #35405 from rohitwaghchaure/fixed-available-qty-issue
fix: available qty not fetching for raw material in PP
2023-05-24 14:24:53 +05:30
Rohit Waghchaure
8e3463c4ef fix: available qty not fetching for raw material in PP 2023-05-24 14:12:58 +05:30
Gursheen Kaur Anand
c1f1a033c9 fix: tab-uniformity (#35400)
Made Doctype tabs uniform

Co-authored-by: Sagar Sharma <sagarsharma.s312@gmail.com>
2023-05-24 12:45:00 +05:30
Anand Baburajan
edb7b0db8f fix: incorrect depr schedule and posting dates on selling of existing assets [dev] (#35398)
* fix: calc depr amount properly on selling of existing assets and fix incorrect posting dates

* chore: get number_of_depreciations_booked properly

* chore: fix test_gle_made_by_asset_sale_for_existing_asset
2023-05-24 12:29:46 +05:30
Rohit Waghchaure
3f548ac910 fix: Stock Analytics and Warehouse wise Item Balance Age and Value issue 2023-05-23 17:06:11 +05:30
Rohit Waghchaure
545b2d32cd fix: balance quantity 2023-05-23 17:06:11 +05:30
Rohit Waghchaure
d9979b2ffb refactor: stock balance report 2023-05-23 17:06:11 +05:30
Ankush Menat
b0eb72ffac fix: replace quotation with invoice in first onboarding (#35389)
[skip ci]
2023-05-23 15:35:55 +05:30
Sagar Sharma
3940deb31c Merge pull request #35303 from s-aga-r/FIX-34761
fix: Pick List TypeError
2023-05-23 14:20:49 +05:30
Sagar Sharma
a111917114 fix: Pick List TypeError 2023-05-23 12:57:48 +05:30
Sagar Sharma
00bb8add40 Merge pull request #35380 from CodeVenturers/OpenContrib
fix: TypeError while saving Job card
2023-05-23 10:49:42 +05:30
vishnu
8c34cc0e00 fix: use flt instead of mandatory field 2023-05-23 04:27:50 +00:00
rohitwaghchaure
4cb9cbee06 Merge pull request #35381 from rohitwaghchaure/fixed-skip-available-qty-for-sub-assembly
feat: provision to skip available sub assembly items in the production plan
2023-05-23 09:39:09 +05:30
Sagar Sharma
4fee4fb3b7 Merge branch 'develop' into PACKING-SLIP-FOR-DN-PACKED-ITEMS 2023-05-23 07:10:09 +05:30
Rohit Waghchaure
9dd566c1e8 test: test case to skip available qty for sub-assembly items 2023-05-23 01:02:16 +05:30
Rohit Waghchaure
64751ec4d9 feat: provision to skip available sub assembly items in the production plan 2023-05-23 00:16:48 +05:30
vishnu
a209fb4b64 fix: error while saving job card 2023-05-22 18:00:50 +00:00
Sagar Sharma
9308cd9b57 Merge pull request #35376 from s-aga-r/FIX-ISS-23-24-00368-2
fix: don't recalculate rate for SCR rejected warehouse SLE
2023-05-22 15:45:30 +05:30
Sagar Sharma
57ee473fa4 fix: don't recalculate rate for SCR rejected warehouse SLE 2023-05-22 15:07:39 +05:30
Sagar Sharma
7e4dc11c4c Merge branch 'develop' into PACKING-SLIP-FOR-DN-PACKED-ITEMS 2023-05-21 08:34:41 +05:30
Ankush Menat
ba61865ee6 chore: drop outdated navigation video
new stuff is in work, this one is actually counter-productive rn.
2023-05-20 19:45:59 +05:30
rohitwaghchaure
44cd76bb48 Merge pull request #35365 from rohitwaghchaure/create-reposting-entries-from-report
feat: provision to make reposting entries from Stock and Account Value Comparison Report
2023-05-20 17:06:13 +05:30
Rohit Waghchaure
7b818e9d34 feat: provision to make reposting entries from Stock and Account Value Comparison Report 2023-05-19 18:53:40 +05:30
Deepesh Garg
68eee35c5d Merge pull request #35346 from nabinhait/account-closing-balance-patch-fix
fix: account closing balance patch
2023-05-19 11:09:39 +05:30
rohitwaghchaure
216983a729 Merge pull request #34909 from ihosseinu/get_incoming_rate_v14_fix
Get incoming rate v14 fix
2023-05-19 09:56:32 +05:30
Sagar Sharma
44b0bc2d76 Merge branch 'develop' into PACKING-SLIP-FOR-DN-PACKED-ITEMS 2023-05-19 09:20:21 +05:30
ruthra kumar
f143bd1bec Merge pull request #35355 from ruthra-kumar/fix_possible_type_erro_on_so_creation_from_quotation
fix: possible type error on quotation -> sales order creation
2023-05-18 13:31:29 +05:30
ruthra kumar
b2290c6f57 fix: possible type error on quotation -> sales order creation 2023-05-18 12:48:15 +05:30
ruthra kumar
1587ce3bfb Merge pull request #35335 from ruthra-kumar/incorrect_tds_calcuation_if_supplier_has_different_category
fix: tds incorrectly calculated for invoice that are below threshold
2023-05-18 12:38:31 +05:30
ruthra kumar
73bcd4451a Merge pull request #35352 from niyazrazak/patch-12
fix: create sales order
2023-05-18 12:07:35 +05:30
ruthra kumar
132846bbd1 fix(test): cumulative threshold checks 2023-05-18 12:00:59 +05:30
MOHAMMED NIYAS
90ddf1c0f0 fix: create sales order
Getting error while clicking create sales order button from quotation

Taceback (most recent call last):
  File "apps/frappe/frappe/app.py", line 66, in application
    response = frappe.api.handle()
  File "apps/frappe/frappe/api.py", line 54, in handle
    return frappe.handler.handle()
  File "apps/frappe/frappe/handler.py", line 45, in handle
    data = execute_cmd(cmd)
  File "apps/frappe/frappe/handler.py", line 83, in execute_cmd
    return frappe.call(method, **frappe.form_dict)
  File "apps/frappe/frappe/__init__.py", line 1607, in call
    return fn(*args, **newargs)
  File "apps/frappe/frappe/model/mapper.py", line 36, in make_mapped_doc
    return method(source_name)
  File "apps/erpnext/erpnext/selling/doctype/quotation/quotation.py", line 263, in make_sales_order
    return _make_sales_order(source_name, target_doc)
  File "apps/erpnext/erpnext/selling/doctype/quotation/quotation.py", line 333, in _make_sales_order
    doclist = get_mapped_doc(
  File "apps/frappe/frappe/model/mapper.py", line 144, in get_mapped_doc
    postprocess(source_doc, target_doc)
  File "apps/erpnext/erpnext/selling/doctype/quotation/quotation.py", line 291, in set_missing_values
    for d in customer.get("sales_team"):
TypeError: 'NoneType' object is not iterable
2023-05-18 10:23:58 +05:30
rohitwaghchaure
ffb353032d Merge branch 'develop' into get_incoming_rate_v14_fix 2023-05-18 06:13:52 +05:30
rohitwaghchaure
6fbcc3d196 Merge pull request #35298 from CodeVenturers/OpenContirb
fix: Creating landed cost voucher from connections
2023-05-18 06:00:07 +05:30
Anand Baburajan
8c53e0f004 fix: depreciation schedule for existing assets [dev] (#35256)
* fix: depreciation schedule for existing assets

* chore: correct logic for existing assets and fix test

* chore: properly check if depr amount is non zero
2023-05-17 22:29:09 +05:30
Nabin Hait
2b8c39eee9 fix: account closing balance patch 2023-05-17 22:05:46 +05:30
Sagar Sharma
cf0d37cd82 Merge pull request #35306 from s-aga-r/FIX-35014
fix: Pick List Status
2023-05-17 18:12:30 +05:30
Sagar Sharma
fcea907cf9 Merge branch 'develop' into FIX-35014 2023-05-17 16:09:21 +05:30
Sagar Sharma
9fb8b1827d fix: Pick List Status 2023-05-17 16:07:58 +05:30
Ankush Menat
e5c86bc2e8 fix: consider 0 if rate/qty are null (#35338)
[skip ci]
2023-05-17 16:04:49 +05:30
Sagar Sharma
0f3230f581 Merge pull request #35337 from s-aga-r/FIX-SCR-CONSUMED-QTY-UX
fix(ux): SCR consumed-qty read-only property
2023-05-17 15:57:30 +05:30
Sagar Sharma
adf2474d9d fix(ux): SCR consumed-qty read-only property 2023-05-17 15:12:47 +05:30
ruthra kumar
84b7c1bba0 fix: tds incorrectly calculated for invoice that are below threshold
Two purchase invoices for the same supplier, using different tax
withholding categories have this issue.

| Category | single | cumulative |
|----------+--------+------------|
| cat1     |    100 |        500 |
| cat2     |   1000 |       5000 |

1. PINV1 of net total: 105/- uses cat1. TDS is calculated as it
breached single threshold
2. PINV2 of net total: 200/- uses cat2. TDS incorrectly calculated as
PINV1 already has TDS calculated and 'consider_party_ledger_amount' is enabled.
2023-05-17 13:55:41 +05:30
Sagar Sharma
42804306fd Merge branch 'develop' into PACKING-SLIP-FOR-DN-PACKED-ITEMS 2023-05-17 13:17:59 +05:30
ruthra kumar
e927f6cab1 Merge pull request #35239 from ashish-greycube/patch-8
fix: in payment_entry  difference amount cal is broken
2023-05-17 10:25:55 +05:30
ruthra kumar
0da6c1688b fix: unable to create partial invoice with auto fetch terms enabled (#35285)
fix: fetch so/po terms if auto fetch is enabled
2023-05-16 18:57:42 +05:30
rohitwaghchaure
96e6014d12 Merge pull request #35328 from rohitwaghchaure/fixed-create-reposting-entry-for-cancelled-documents
fix: force to do reposting for cancelled document
2023-05-16 17:31:45 +05:30
Ashish Shah
ae4e56747c refactor: use 'flt' for base_total_taxes_and_charges
difference_amount calculation is broken, as calculation gives NaN. Fix is make frm.doc.base_total_taxes_and_charges as flt(frm.doc.base_total_taxes_and_charges)
2023-05-16 16:55:11 +05:30
Rohit Waghchaure
6e661e7c0e fix: force to do reposting for cancelled document 2023-05-16 16:23:52 +05:30
ruthra kumar
776a83066d fix: cancelled vouchers in tax withheld vouchers list (#35309) 2023-05-16 15:54:46 +05:30
Ankush Menat
5574d9a72d fix(UX): misc "home" onboarding improvements (#35319)
* fix(UX): cleanup "Home" onboarding

- Remove company, letterhead, data import etc from home onboarding step

* fix(UX): Show quick entry for item

* chore: fix copy here and there
2023-05-16 13:38:55 +05:30
Rucha Mahabal
9feda1b829 perf: cache and simplify queries for holiday list (#35315) 2023-05-16 13:11:47 +05:30
rohitwaghchaure
5c2d7701ea Merge pull request #35312 from rohitwaghchaure/fixed-item-list-view-not-working
fix: item list view not working
2023-05-16 01:09:44 +05:30
Rohit Waghchaure
0489e30244 fix: item list view not working 2023-05-16 00:48:52 +05:30
rohitwaghchaure
3f5ce43185 Merge pull request #35138 from s-aga-r/FIX-ISS-23-24-00368
fix: recalculate costs in SCR while reposting
2023-05-15 16:26:04 +05:30
rohitwaghchaure
8afbb06a33 Merge branch 'develop' into FIX-ISS-23-24-00368 2023-05-15 13:42:20 +05:30
Wolfram Schmidt
c236979508 fix: Update de.csv (#35278)
added many fixes on the base of 'No' which is often wrongly translated to 'Kein'.

Also removed translation of Naming Seris like ACC-INV-.YYYY.- to ACC-INV-.YYYY.-
2023-05-15 13:25:23 +05:30
Smit Vora
2a609616d9 fix: port option for additional_conditions in item wise sales register (#35187)
Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-05-15 13:24:39 +05:30
vishnu
f2ceb00379 fix: Creating landed cost voucher from connections 2023-05-14 09:35:38 +00:00
Indrajith.vs
0c8276ec82 fix: sales person allocated amount calculation error nonetype and float (#35293)
fix: sales person allocated amount calculation error nontype and float
2023-05-14 11:47:46 +05:30
Raffael Meyer
870b02b03c fix: allow over-payment against SO (#35079) 2023-05-14 08:59:58 +05:30
Daizy Modi
19cd687784 fix: function batch_no should only be declared once (#35115)
fix: remove twice event call of `batch_no` to update batch qty
2023-05-14 08:56:25 +05:30
Kevin Shenk
26c5cfabdc feat: copy project from timesheet to invoice (#35146)
copy project from timesheet to invoice
2023-05-14 08:49:28 +05:30
HarryPaulo
e12e3bb012 fix: allow search leads by doctype search fields
* fix: allow search leads by doctype search fields

* fix: allow search leads by doctype search fields, linters fix
2023-05-14 08:08:47 +05:30
Phanupong Janthapoon
2b59a95162 fix: share_transfer display wrong currency symbo
In multi-companies setting, on amount and rate field of  Share Transfer
doctype are displaying wrong currency symbol, when create a
Share Transfer of others company that has different currency than
the main company. This due to the lack of `options` on those fields.

To fix this, add `options` to `amount` and `rate` fields.
2023-05-14 08:06:58 +05:30
rohitwaghchaure
e6f092d257 Merge pull request #35289 from rohitwaghchaure/fixed-inventory-dimesion-for-inter-compnay-trasfer-return
fix: inventory dimension for returned inter company transfer
2023-05-13 14:26:17 +05:30
Rohit Waghchaure
38aaba5720 fix: inventory dimension for inter company transfer return use case 2023-05-13 13:00:05 +05:30
Sagar Sharma
81a57e4e41 Merge branch 'develop' into stock-reservation 2023-05-13 09:44:06 +05:30
Sagar Sharma
9b617cc062 Merge branch 'develop' into PACKING-SLIP-FOR-DN-PACKED-ITEMS 2023-05-13 09:43:54 +05:30
Sagar Sharma
e17eeec619 Merge branch 'develop' into FIX-ISS-23-24-00368 2023-05-13 09:43:44 +05:30
Sagar Sharma
59f9d41756 Merge pull request #35275 from s-aga-r/FIX-35272
fix: add missing options for `Content Align`
2023-05-13 09:34:45 +05:30
Sagar Sharma
88ab075b11 Merge branch 'develop' into FIX-35272 2023-05-13 09:33:25 +05:30
rohitwaghchaure
e7bb6ad31c Merge pull request #35224 from rohitwaghchaure/fixed-inventory-dimension-for-material-transfer-not-working
fix: inventory dimension for material transfer not working
2023-05-13 02:15:18 +05:30
Rohit Waghchaure
6798b900ef fix: inventory dimension for material transfer not working 2023-05-13 01:44:06 +05:30
Sagar Sharma
4aff3c9a50 Merge branch 'develop' into FIX-35272 2023-05-12 15:06:47 +05:30
Sagar Sharma
d16caa2d2c fix: add missing options for Content Align 2023-05-12 15:06:03 +05:30
rohitwaghchaure
0723fbc108 Merge pull request #35273 from rohitwaghchaure/fixed-incorrect-packing-list
fix: incorrect packing items
2023-05-12 14:42:57 +05:30
Rohit Waghchaure
a686b8c337 fix: incorrect packing items 2023-05-12 14:12:29 +05:30
rohitwaghchaure
46a2bd8986 Merge pull request #35268 from rohitwaghchaure/fixed-incorrect-bom-filter-issue
fix: BOM item filter issue
2023-05-12 13:09:57 +05:30
Rohit Waghchaure
2879cb7c28 fix: bom item filter issue 2023-05-12 13:08:37 +05:30
rohitwaghchaure
4aa1508f04 Merge pull request #35261 from rohitwaghchaure/fixed-timeout-error-for-stock-entry-more-than-6-mmoths
fix: enqueue submit/cancel action for stock entry to avoid time out error
2023-05-12 12:32:33 +05:30
Nabin Hait
ca8b587730 Merge pull request #35178 from nabinhait/account-closing-balance-patch
fix: account closing balance patch
2023-05-12 12:07:45 +05:30
Sagar Sharma
b22f9a234b Merge branch 'develop' into FIX-ISS-23-24-00368 2023-05-12 11:55:12 +05:30
Sagar Sharma
9c72c2a6cb refactor: use calculate_items_qty_and_amount() to update scr items rate 2023-05-12 11:50:27 +05:30
Sagar Sharma
d6433f803b refactor(minor): rename function to be more descriptive 2023-05-12 11:45:33 +05:30
Sagar Sharma
46c1bef446 Merge branch 'develop' into PACKING-SLIP-FOR-DN-PACKED-ITEMS 2023-05-12 11:06:00 +05:30
Rohit Waghchaure
2d6f112727 fix: test case 2023-05-12 10:51:14 +05:30
Rohit Waghchaure
7a3801578c fix: enqueue submit/cancel action for stock entry to avoid time out error 2023-05-11 23:20:12 +05:30
Nabin Hait
f5cc41e182 fix: account closing balance patch 2023-05-10 16:41:47 +05:30
Ankush Menat
2ea38333f0 refactor: use job_id instead of job_name (#35242)
depends on https://github.com/frappe/frappe/pull/20951
2023-05-10 13:26:10 +05:30
rohitwaghchaure
5d43b35d20 Merge pull request #35230 from rohitwaghchaure/fixed-serial-no-issue-stock-reco
fix: Changed type of column 'serial_no' in Stock Reconciliation to fix Data too Long error
2023-05-09 19:54:24 +05:30
rohitwaghchaure
bf29ec4341 Merge pull request #35227 from rohitwaghchaure/fixed-do-not-include-manufacturing-item
fix: non manufacturing items/fixed asset items in BOM
2023-05-09 18:47:36 +05:30
Rohit Waghchaure
1a673fd424 fix: Changed type of column 'serial_no' in Stock Reconciliation to fix Data too long error 2023-05-09 18:45:19 +05:30
ruthra kumar
b8971c7add Merge pull request #35216 from rtdany10/broken-empty-row-save
fix: broken save on empty row existance
2023-05-09 18:31:17 +05:30
Rohit Waghchaure
aba8431d70 fix: non manufacturing items/fixed asset items in BOM 2023-05-09 16:48:30 +05:30
rohitwaghchaure
d5f123f2e1 Merge pull request #35220 from rohitwaghchaure/fixed-performance-issue-for-ste-mr
fix: added search index to improve performance
2023-05-09 14:33:56 +05:30
Rohit Waghchaure
80ea22b56c fix: added search index to improve performance 2023-05-09 12:42:17 +05:30
ruthra kumar
afe9d7614b Merge pull request #35212 from ruthra-kumar/chore_change_throw_to_msgprint
chore: convert throw to msgprint in payment reconciliation job hook
2023-05-08 17:57:13 +05:30
Dany Robert
d9b231aa16 fix: broken save on empty row existance 2023-05-08 12:26:47 +00:00
Anand Baburajan
67f3304ab4 fix: handle empty FBs properly in TB and GL [develop] (#35190)
fix: handle empty FBs properly in TB and GL
2023-05-08 16:55:05 +05:30
Anand Baburajan
5a3acab110 fix: handle empty FBs properly in TB and GL [develop] (#35190)
fix: handle empty FBs properly in TB and GL
2023-05-08 16:54:00 +05:30
Sagar Sharma
12785101d9 Merge branch 'develop' into stock-reservation 2023-05-08 16:47:40 +05:30
Sagar Sharma
2e9278ef90 Merge branch 'develop' into PACKING-SLIP-FOR-DN-PACKED-ITEMS 2023-05-08 16:47:30 +05:30
ruthra kumar
73134d57bf chore: convert throw to msgprint 2023-05-08 16:42:12 +05:30
ruthra kumar
446f3d12eb Merge pull request #35153 from ruthra-kumar/fetch_sales_team_from_customer_master
fix: fetch default sales team on Quotation -> Sales Order creation
2023-05-08 14:19:28 +05:30
ruthra kumar
6315d9f836 Merge pull request #35142 from ruthra-kumar/fix_bypass_check_in_customer_group
fix: ineffective bypass flag for Credit Limit in Customer Group
2023-05-08 14:10:31 +05:30
ruthra kumar
34a5f24026 Merge pull request #35186 from ruthra-kumar/child_account_should_inherit_parent_account_currency
fix: child acc will inherit acc currency if explicitly specified
2023-05-08 14:09:46 +05:30
ruthra kumar
f6ea8fd8d7 test: currency inheritance on child accounts 2023-05-08 13:30:39 +05:30
rohitwaghchaure
ecc80a8504 Merge pull request #34998 from Vishnu7025/develop
fix: update workstation hour rate when workstation change in job card
2023-05-08 09:25:38 +05:30
rohitwaghchaure
328c3369a2 Merge pull request #35200 from rohitwaghchaure/fixed-accepted-warehouse-and-supplier-warehouse-issue
fix: error regarding accepted and supplier warehouse
2023-05-08 09:23:54 +05:30
rohitwaghchaure
457f7f941c Merge pull request #35196 from rohitwaghchaure/fixed-order-of-reposting-entry
fix: pick the in progress reposting entries first
2023-05-08 09:23:34 +05:30
Rohit Waghchaure
15f5f98858 fix: error regarding accepted and supplier warehouse 2023-05-07 20:27:17 +05:30
rohitwaghchaure
530edaf3d1 Merge branch 'develop' into develop 2023-05-07 19:58:42 +05:30
rohitwaghchaure
40e3747b93 Merge branch 'develop' into fixed-order-of-reposting-entry 2023-05-07 01:39:23 +05:30
rohitwaghchaure
c3ca5d0894 Merge pull request #35197 from rohitwaghchaure/fix-incorrect-fg-item-qty-in-job-po
fix: incorrect fg item quantity in subcontracted PO
2023-05-07 01:38:43 +05:30
Ritwik Puri
140cec8eb2 Merge branch 'develop' into fix-incorrect-fg-item-qty-in-job-po 2023-05-06 22:49:09 +05:30
Rohit Waghchaure
af16fbb0a3 fix: incorrect fg item quantity in subcontracted PO 2023-05-06 20:30:53 +05:30
Rohit Waghchaure
c8a4791d9b fix: pick the in progress reposting entries first 2023-05-06 20:09:15 +05:30
Deepesh Garg
23e7c1480f Merge pull request #34897 from barredterra/fix-translation-files
fix: translation files
2023-05-06 18:24:50 +05:30
ruthra kumar
abe691c03d fix: child acc will inherit acc currency if explicitly specified 2023-05-06 10:40:41 +05:30
Hossein Yousefian
27d71e9ec1 Merge branch 'develop' into get_incoming_rate_v14_fix 2023-05-06 08:12:36 +03:30
Nabin Hait
713fa67b96 fix: account closing balance patch 2023-05-05 17:54:34 +05:30
rohitwaghchaure
7fb1e5bdcd Merge pull request #35167 from rohitwaghchaure/fixed-job-card-excess-material-trafer
fix: not allow to transfer excess materials against the job card
2023-05-04 19:10:46 +05:30
Rohit Waghchaure
8167b24219 fix: not allow to transfer excess materials against the job card 2023-05-04 18:24:16 +05:30
rohitwaghchaure
3993bfd510 Merge pull request #35161 from rohitwaghchaure/configure-notify-reposting-role
feat: configuration to notify reposting errors to specific role
2023-05-04 17:35:14 +05:30
rohitwaghchaure
2bf771683c Merge pull request #35158 from rohitwaghchaure/fixed-internal-trasfer-condition
fix: internal transfer condition
2023-05-04 17:01:58 +05:30
Rohit Waghchaure
c7b62011db feat: configuration to notify reposting errors to specific role 2023-05-04 16:49:14 +05:30
Rohit Waghchaure
b5a2ccf21d fix: internal transfer condition 2023-05-04 15:38:35 +05:30
Sagar Sharma
e0b22edb2e test: add test case 2023-05-04 15:07:52 +05:30
ruthra kumar
4d31436917 fix: fetch default sales team on Quotation -> Sales Order creation 2023-05-04 10:45:22 +05:30
Raffael Meyer
9fd0091b60 Merge branch 'develop' into fix-translation-files 2023-05-04 00:26:01 +02:00
rohitwaghchaure
bea8f481b4 Merge pull request #35148 from rohitwaghchaure/fixed-extra-job-card-quantity-issue
fix: over production percentage not considered in validation
2023-05-04 00:13:53 +05:30
Rohit Waghchaure
a84d0af81e fix: over production percentage not considered in validation 2023-05-03 23:22:59 +05:30
rohitwaghchaure
dfee45f7ae Merge pull request #35144 from rohitwaghchaure/feat-reserved-qty-for-production-plan-in-bin
feat: reserve qty against production plan raw materials in BIN
2023-05-03 22:24:05 +05:30
Rohit Waghchaure
06e91e758f feat: reserve qty against production plan raw materials in BIN 2023-05-03 18:21:23 +05:30
ruthra kumar
f9a4972cb6 fix: bypass flag in Customer Group wasn't effective 2023-05-03 16:40:38 +05:30
s-aga-r
7548bb3fbe Merge branch 'develop' into stock-reservation 2023-05-03 12:06:11 +05:30
Sagar Sharma
6bcda38415 Merge branch 'develop' into PACKING-SLIP-FOR-DN-PACKED-ITEMS 2023-05-03 12:01:46 +05:30
s-aga-r
a6cb6c6f47 fix: recalculate costs in SCR while reposting 2023-05-03 11:33:52 +05:30
Anand Baburajan
6864b11f83 fix: handle finance book properly in trial balance and general ledger (#35085)
* fix: get default fb properly and handle different fb and default fb case

* chore: minor UX improvement

* fix: handle FBs properly in general ledger
2023-05-02 20:58:22 +05:30
Sagar Sharma
862041dc0e Merge branch 'develop' into PACKING-SLIP-FOR-DN-PACKED-ITEMS 2023-05-02 19:11:33 +05:30
Vishnu VS
536473a484 Merge branch 'develop' into develop 2023-05-02 17:42:41 +05:30
ruthra kumar
7e24215b3a Merge pull request #35107 from ruthra-kumar/fix_incorrect_paid_amount_if_bank_cash_account_missing
fix: incorrect paid_amount and exchange rate in Payment Entry
2023-05-02 15:07:36 +05:30
ruthra kumar
1d70183d8c Merge pull request #35091 from ruthra-kumar/cost_center_allocation_splits_roundoff
refactor: button to toggle parent doc cost center preference for rounding adjustment amount
2023-05-02 14:07:22 +05:30
ruthra kumar
8f2302a7bf Merge pull request #35061 from ruthra-kumar/refactor_pe_dont_book_gain_loss_for_sales_purchase_orders
refactor: don't book exchange gain/loss for sales/purchase orders
2023-05-02 14:03:17 +05:30
rohitwaghchaure
9aa646512a Merge pull request #35123 from rohitwaghchaure/fixed-performance-issue-delivery-note
fix: timeout error while submitting delivery note
2023-05-01 23:30:14 +05:30
Rohit Waghchaure
2d5ccc07b1 fix: timeout error while submitting delivery note 2023-05-01 21:17:18 +05:30
rohitwaghchaure
a10aab35ff Merge pull request #35118 from rohitwaghchaure/fixed-don-not-allow-to-repost-valuation
fix: don't allow to make reposting for the closed period
2023-05-01 20:41:14 +05:30
mergify[bot]
49674585a5 fix: handle expected_value_after_useful_life properly in asset value adjustment (backport #35117) (#35119)
fix: handle expected_value_after_useful_life properly in asset value adjustment (#35117)

(cherry picked from commit 80230fec3e)

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
2023-05-01 19:59:58 +05:30
Rohit Waghchaure
f751727149 fix: don't allow to make reposting for the closed period 2023-05-01 18:48:29 +05:30
ruthra kumar
ce4e18c8d2 test: Sales/Purchase Orders will not book Exchange gain/loss 2023-05-01 14:09:19 +05:30
ruthra kumar
effb34bbfa refactor: don't book exch gain/loss for sales/purchase orders 2023-05-01 14:08:30 +05:30
Deepesh Garg
ea0b03ae9e fix: Updates in process statement of Accounts (#35064) 2023-05-01 13:09:47 +05:30
ruthra kumar
092c4b4c58 refactor: simplify group by invoice logic 2023-05-01 11:53:43 +05:30
Deepesh Garg
64be694087 fix: Patch for posting closing balances (#35037) 2023-05-01 10:56:46 +05:30
Deepesh Garg
f3b3dabb9a fix: Naming series error in Journal Entry template (#35084) 2023-05-01 10:50:51 +05:30
Sagar Sharma
424bd701f3 Merge branch 'develop' into PACKING-SLIP-FOR-DN-PACKED-ITEMS 2023-05-01 08:05:18 +05:30
s-aga-r
bbcb65894b refactor: use get_product_bundle_list() to get all product bundle at once 2023-05-01 08:04:03 +05:30
s-aga-r
ba61292dfc test: add test case for packed qty validation on DN submit 2023-05-01 07:25:36 +05:30
ruthra kumar
123355392b fix: incorrect paid_amount and exchange rate in PE
If Company master has no default cash or bank account set but Party has
default company bank account set. In this case, paid_amount and
conversion rate are not calculated correctly
2023-04-30 08:36:56 +05:30
Vishnu VS
9fd7a05b40 Merge branch 'develop' into develop 2023-04-29 21:02:54 +05:30
s-aga-r
699532647d refactor: validate_packed_qty() 2023-04-28 23:03:33 +05:30
s-aga-r
b0eb9ea7bd refactor(minor): use set_onload to get unpacked items details 2023-04-28 22:47:27 +05:30
s-aga-r
7742c592c5 test: add test cases for Packing Slip 2023-04-28 21:51:15 +05:30
s-aga-r
da00fc0f16 fix(ux): don't show Create > Packing Slip button if items are already packed 2023-04-28 18:28:28 +05:30
s-aga-r
8d1bccada4 fix(ux): remove Get Items button from Packing Slip 2023-04-28 18:02:24 +05:30
s-aga-r
e75aa4e291 fix(ux): get items on selecting DN in Packing Slip 2023-04-28 17:59:34 +05:30
s-aga-r
269cc96c41 refactor: move js validations to py 2023-04-28 17:47:36 +05:30
s-aga-r
90701c7ae9 fix: validate Packing Slip Item Qty with DN Items 2023-04-28 17:05:51 +05:30
rohitwaghchaure
35ee8d19b0 Merge pull request #35092 from rohitwaghchaure/fixed-reserved-qty-issue-for-dn
fix: not able to create delivery note from sales order
2023-04-28 16:02:35 +05:30
s-aga-r
9e5b102768 fix: make DN item reference mandatory for Packing Slip Item 2023-04-28 15:41:59 +05:30
s-aga-r
372bce4567 fix: Packing Slip Item Qty 2023-04-28 15:26:02 +05:30
Rohit Waghchaure
bdf2f7416a fix: not able to create delivery note from sales order 2023-04-28 15:16:02 +05:30
s-aga-r
0add90e7ec chore: enable no_copy for dn_detail and pi_detail in Packing Slip Item 2023-04-28 15:05:28 +05:30
s-aga-r
77f1e8ce78 fix: update Packed Qty in DN on submit and cancel of Packing Slip 2023-04-28 15:04:41 +05:30
ruthra kumar
4ccce93394 refactor: checkbox to toggle parent doc cost center preference 2023-04-28 14:20:50 +05:30
ruthra kumar
0f3b06cc8a refactor: checkbox in Sales Invoice 2023-04-28 14:20:50 +05:30
ruthra kumar
ebe6787510 refactor: checkbox to toggle parent doc cost center preference 2023-04-28 14:20:48 +05:30
Vishnu VS
bb13c236b9 Merge branch 'develop' into develop 2023-04-28 14:06:12 +05:30
ruthra kumar
b44331c981 refactor: checkbox in purchase invoice 2023-04-28 14:06:04 +05:30
s-aga-r
e6fc281acf feat: add field Packed Qty in Delivery Note Item and Packed Item 2023-04-28 13:20:47 +05:30
Sagar Sharma
d6c5b3e419 Merge pull request #35081 from SolufyPrivateLimited/fix-qc-hyperlink-v14
fix: Hyperlink in Quality Inspection Summary
2023-04-28 12:48:53 +05:30
s-aga-r
75fe9dd3ea fix: don't map items twice
* don't explicitly map Delivery Note Item custom fields to Packing Slip Item, get auto-mapped while mapping the doc.
* call Packing List `set_missing_values` after mapping the doc.
* refactor `get_recommended_case_no`, use `frappe.db.get_value` instead of `frappe.db.sql`.
2023-04-28 10:53:17 +05:30
s-aga-r
ee9f97ca7c fix: remove duplicate items validation 2023-04-28 09:07:03 +05:30
Vishnu VS
489f853ee2 Merge branch 'develop' into develop 2023-04-27 21:17:47 +05:30
s-aga-r
b62bf78814 refactor: packing_slip.js 2023-04-27 19:43:37 +05:30
s-aga-r
380dd73065 fix: map Packed Items while creating Packing Slip 2023-04-27 18:37:32 +05:30
Nihantra Patel
72dd7884a8 fix: Hyperlink in Quality Inspection Summary 2023-04-27 17:04:39 +05:30
ruthra kumar
787313b875 Merge pull request #35077 from SolufyPrivateLimited/fix-gp-link-14
fix: Report link, option, and added a link for Sales Person in GP
2023-04-27 16:40:45 +05:30
s-aga-r
eca77134ae feat: add field pi_detail in Packing Slip 2023-04-27 15:48:02 +05:30
Nihantra Patel
6dfca79af3 fix: Report link, option, and added a link for Sales Person in GP 2023-04-27 15:04:50 +05:30
Vishnu VS
06e458c745 Merge branch 'develop' into develop 2023-04-27 12:24:29 +05:30
rohitwaghchaure
01bfd2ab67 Merge pull request #35066 from rohitwaghchaure/fixed-delivered-qty-issue-while-making-mr
fix: don't create material request from sales order against delivered items
2023-04-27 09:05:36 +05:30
Rohit Waghchaure
1e2deee579 fix: don't create material request from sales order against the delivered items 2023-04-26 20:30:53 +05:30
Vishnu VS
f68eef833c Update erpnext/manufacturing/doctype/job_card/job_card.py
Co-authored-by: Marica <maricadsouza221197@gmail.com>
2023-04-26 20:25:43 +05:30
Vishnu VS
5c94f2cc52 Update erpnext/manufacturing/doctype/job_card/job_card.py
Co-authored-by: Marica <maricadsouza221197@gmail.com>
2023-04-26 20:25:15 +05:30
Vishnu VS
25d0119b7e Merge branch 'develop' into develop 2023-04-26 18:56:09 +05:30
HarryPaulo
3be1ab9b8d fix: allow submit delivery note when the sales order was billed... (#34910) 2023-04-25 21:54:41 +05:30
Kitti U. @ Ecosoft
c36dc3dc57 fix: v14, Bank Reconcile Tools not cover case JV debit bank (#35000) 2023-04-25 21:34:28 +05:30
rohitwaghchaure
5e37308b5e Merge pull request #35050 from Nandhinidevi123/workstation_filter
add if condition for workstation filter
2023-04-25 21:28:41 +05:30
rohitwaghchaure
b24704740b Merge pull request #34918 from s-aga-r/FIX-ISS-22-23-06298
perf: Journal Entries
2023-04-25 21:27:52 +05:30
mergify[bot]
ab0f7794b7 fix: wrong qty of remaining work orders to be created when using "Create" > "Work Order" (#34726)
fix: wrong qty of remaining work orders to be created when using "Create" > "Work Order" (#34726)

* fix: convert asynchronous field update to synchronous

* fix: wrong qty of remaining work orders to be created when using "Create" > "Work Order"

(cherry picked from commit 189b020d22)

Co-authored-by: danjeremynavarro <46537526+danjeremynavarro@users.noreply.github.com>
2023-04-25 21:08:50 +05:30
tundebabzy
3d90b970d1 fix: click handler should not attempt indexed access of empty array (#35013)
fix: click handler should not attempt indexed access
of empty array
2023-04-25 20:57:59 +05:30
Ernesto Ruiz
c4512d552e chore: Add translate function to Depreciation Journal Entry Remark (#35022)
chore: Add translate function to Depreciation Journal Entry Remark
2023-04-25 20:56:53 +05:30
Deepesh Garg
f88431a79a fix: Common party JV cost center (#35008) 2023-04-25 20:54:22 +05:30
Raffael Meyer
d6bc8bba8b fix: per_billed condition for Payment Entry (#34969) 2023-04-25 20:51:11 +05:30
Nandhinidevi123
74fb2bec3a add if condition for workstation filter 2023-04-25 20:08:35 +05:30
Deepesh Garg
f7b50f2ade fix: Unable to allocate advance against invoice (#35007) 2023-04-25 19:18:45 +05:30
Nabin Hait
72b5c1f70a fix: Use set instead of db_set as it is called from validate (#34967) 2023-04-25 19:18:08 +05:30
Deepesh Garg
ecea9b44a3 fix: Payment entry with TDS in bank reco statement (#34961) 2023-04-25 19:17:13 +05:30
Solufy Solution
f1acc5fabb fix: Bulk Payment Entry from PO/SO (#34942)
Co-authored-by: Nihantra Patel <n.patel.serpentcs@gmail.com>
2023-04-25 19:16:30 +05:30
HarryPaulo
22290c2694 fix: respect title_field from doctype to bulk transactions (#34928) 2023-04-25 19:13:53 +05:30
Deepesh Garg
b545e3def0 fix: Add company field to lower deduction certificate (#34914) 2023-04-25 19:07:45 +05:30
Ankush Menat
6de71eb158 fix: pass reference_doctype in link queries (#35038) 2023-04-25 18:33:31 +05:30
Anand Baburajan
e08d636bf7 fix: use filter_by_finance_book instead of only_depreciable_assets in fixed asset register (#35031)
fix: use filter_by_finance_book instead of only_depreciable_assets
2023-04-25 15:16:50 +05:30
Sagar Sharma
31cdfa395a Merge branch 'develop' into FIX-ISS-22-23-06298 2023-04-25 13:57:34 +05:30
s-aga-r
e782a054c8 refactor: get_stock_value_on() to get stock value of multiple warehouses at once 2023-04-25 13:54:36 +05:30
Anand Baburajan
ca388ed9cd fix: value of depreciable assets not updating after manual depr entry [develop] (#35020)
* fix: value of depreciable assets not updating after manual depr entry

* chore: add asset depr schedule to jv's ignore_doctypes_on_cancel_all
2023-04-25 12:45:05 +05:30
rohitwaghchaure
04902e1b60 Merge pull request #35026 from frappe/revert-34929-fixed-stock-and-account-value-report
Revert "fix: Incorrect difference value in Stock and Account Value Comparison…"
2023-04-25 12:08:48 +05:30
rohitwaghchaure
7a63fbef4f Revert "fix: Incorrect difference value in Stock and Account Value Comparison…" 2023-04-25 12:01:26 +05:30
ruthra kumar
d70f5eef10 Merge pull request #34974 from frappe/revert-33699-tds_report_percentage
Revert "fix: Rate from LDC in TDS reports"
2023-04-25 11:17:04 +05:30
ruthra kumar
20226d0a47 Merge branch 'develop' into revert-33699-tds_report_percentage 2023-04-25 10:43:18 +05:30
ruthra kumar
cb7a99cbaa Revert "fix: Rate from LDC in TDS reports (#33699)"
This reverts commit db9beb3cdd.
2023-04-25 10:13:07 +05:30
Vishnu VS
cdb05cd310 Merge branch 'develop' into develop 2023-04-25 09:29:47 +05:30
Sagar Sharma
58dbf7fc24 Merge branch 'develop' into stock-reservation 2023-04-24 22:58:16 +05:30
s-aga-r
bf4a57a37c fix: miscellaneous
fix: don't reserve stock in group warehouse
fix: partial reservation in multiple warehouses
feat: add prompt to select warehouse and qty for reservation in SO
2023-04-24 22:19:09 +05:30
rohitwaghchaure
291845e461 Merge pull request #35015 from rohitwaghchaure/incorrect-or-cond-delivery-note-issue
fix: incorrect OR condition causing timeout error (For more than 50 line items)
2023-04-24 18:06:59 +05:30
rohitwaghchaure
5d8bf56cb9 Merge pull request #35012 from rohitwaghchaure/fixed-incorrect-bom-end-of-life
fix: item not showing in the BOM
2023-04-24 18:06:37 +05:30
Rohit Waghchaure
379b215aea fix: incorrect OR condition causing timeout error 2023-04-24 17:32:32 +05:30
Rohit Waghchaure
02c3b41dc2 fix: item not showing in the BOM 2023-04-24 14:50:27 +05:30
s-aga-r
388f85b109 refactor: Stock Reservation code in sales_order.js 2023-04-24 12:04:22 +05:30
s-aga-r
e517c06847 chore: add warehouse info in SRE msg 2023-04-23 15:45:58 +05:30
s-aga-r
0b5f03e88c Revert "fix: Reserve and Unreserve buttons visibility in SO"
This reverts commit cdb3181691.
2023-04-23 15:41:48 +05:30
Vishnu VS
dc0e64a72d Merge branch 'frappe:develop' into develop 2023-04-22 23:15:42 +05:30
ruthra kumar
ed14d1ce44 feat: Reconcile Payments in background (#34596)
* feat: auto reconcile in background

* chore: Option to enable auto reconciliation in settings

* refactor: validate if feature is enabled in settings

* refactor: check for running job while using reconciliation tool

* chore: using doc to get filter values

* chore: use frappe.db.get_value in validations

* chore: cleanup commented out code

* chore: replace get_list with get_all

* chore: use block scope variable

* chore: type information for functions

* refactor: flag to ignore job validation check

* refactor: update parent doc status if all reconciled

* chore: create test_records file

* test: create a bunch of vouchers for testing auto reconcile

* chore: renamed auto_reconcile to process_payment_reconciliation

* chore: another child doctype to hold payments

* chore: remove duplicate field

* chore: add fetched payments to log

* chore: Popup comment message update

* chore: replace get_all with get_value

* chore: replace label in settings page

* chore: remove unit test and records

* refactor: status in reconciliation log

* refactor: set status in log as well

* chore: fix field name

* chore: change triggered job name

* chore: use status field in list view of log

* chore: status while there are no allocations

* refactor: split trigger function into two

* chore: adding cancelled status

* refactor: function trigger queued docs

* chore: cron job scheduled

* chore: fixing accouts settings json file

* chore: typos and variable scope

* chore: use 'pluck' in db call

* chore: remove redundant whitelist decorator

* chore: use single DB call to fetch values

* chore: replace get_all with get_value

* refactor: use raw db calls to fetch reconciliation log records

Using get_doc on `Process Payment Reconciliation Log` is costly when
handling large volumes of invoices.

Use raw frappe.db.get_all to selectively pull status and reconciled count

* chore: update status on successful batch operation

* chore: make payment table readonly

* chore: ability to pause the background job

* chore: remove isolate_each_allocation

* chore: more description in progress bar

* refactor: partially working state

* refactor: update reconcile flag and setting hard limits for fetching

* chore: make allocation editable -- NEED TO REVERT

* chore: pause button

* refactor: skip setter function in Payment Entry for better performan

* refactor: split reconcile function and skip a setter function

1. Split reconcile function into 2
2. While reconciling against payment entry, skip a
set_missing_ref_details setter method

* chore: increase payment limit

* refactor: replace frappe.db.get_all with frappe.db.get_value

* chore: remove unwanted doctypes

* refactor: make allocation table readonly

* perf: update ref_details only for newly linked invoices

* chore: rename skip flag

* refactor(UI): receivable_payable field should auto populate

* refactor: no control statements in finally block

* chore: cleanup section and rename checkbox

* chore: update new fieldname in code

* chore: update error msg

* refactor: start and pause integrated into status

pause checkbox has been removed

* refactor: added cancelled status to the log doctype

1. Moved the status section to the bottom in parent doc
2. Using alerts to indicate Job trigger status
2023-04-22 17:24:35 +05:30
rohitwaghchaure
58a5f816db Merge pull request #34994 from rohitwaghchaure/fixed-duplicate-repost-entries-of-same-voucher
fix: duplicate reposting entries of same voucher
2023-04-22 14:08:06 +05:30
Rohit Waghchaure
f2253dd645 fix: duplicate reposting entries of same voucher 2023-04-22 11:16:12 +05:30
s-aga-r
0cd10a50d2 Merge branch 'develop' into stock-reservation 2023-04-22 10:04:46 +05:30
s-aga-r
28d0629df1 chore: add depends_on condition for Reserve Stock field in SO 2023-04-22 10:01:00 +05:30
s-aga-r
cdb3181691 fix: Reserve and Unreserve buttons visibility in SO 2023-04-22 09:49:47 +05:30
s-aga-r
b70273b988 chore: remove Enable Stock Reservation field description 2023-04-22 08:49:31 +05:30
rohitwaghchaure
9fa72cb9d8 Merge pull request #34982 from rohitwaghchaure/fixed-added-validation-for-extra-job-card
fix: added validation for extra job cards
2023-04-21 18:50:39 +05:30
Ankush Menat
ac871797b2 fix: SLA permissions (#34981) 2023-04-21 18:05:29 +05:30
rohitwaghchaure
56d62cae7a Merge pull request #34980 from rohitwaghchaure/fix-inter-transfer-validation
fix: validation for internal transfer entry
2023-04-21 17:45:54 +05:30
s-aga-r
7e8fd8f324 chore: update reserved stock SLE validation 2023-04-21 17:44:44 +05:30
Rohit Waghchaure
6a0b7c9e8c fix: added validation for extra job card 2023-04-21 17:34:22 +05:30
Rohit Waghchaure
19911b48fd fix: validation for internal transfer entry 2023-04-21 16:56:09 +05:30
s-aga-r
9a37ac6c25 refactor: sum up SLE value in query 2023-04-21 13:28:14 +05:30
HENRY Florian
af8da53cf4 fix: FEC report for France accountancy (#34781)
* fix: FEC report for France Accountancy legal requirement

* fix: FEC report for France Accountancy legal requirement

* fix: change to query standard

* fix: change to query standard

* fix: columns to standard dict

* fix: columns to standard dict

* fix: columns to data

* refactor: french report FEC

* refactor: french report FEC (2)

---------

Co-authored-by: barredterra <14891507+barredterra@users.noreply.github.com>
2023-04-21 13:26:32 +05:30
Deepesh Garg
a02705ded7 chore: Move source and campaign to more info section (#34946) 2023-04-21 13:25:32 +05:30
ruthra kumar
3ec1597860 Merge pull request #34940 from ruthra-kumar/broken_set_exchange_gain_loss_btn_in_payment_entry
fix: broken 'set exchange gain/loss' btn in payment entry
2023-04-21 09:47:53 +05:30
Hossein Yousefian
984eb2a0dd Merge branch 'develop' into get_incoming_rate_v14_fix 2023-04-20 16:50:34 +03:30
rohitwaghchaure
f218df460f Merge pull request #34958 from rohitwaghchaure/removed-depends-on-for-employee-detail
fix: removed depends on for the Employee Detail section
2023-04-20 18:03:46 +05:30
rohitwaghchaure
6259c81adc Merge pull request #34960 from rohitwaghchaure/fixed-stock-entry-type
fix: stock entry type issue
2023-04-20 18:03:23 +05:30
Sagar Vora
83a4c6dda8 Merge pull request #34738 from resilient-tech/regional++ 2023-04-20 05:17:57 -07:00
Sagar Vora
776b56ccd1 fix: use functools.wraps to preserve doc signature 2023-04-20 05:17:30 -07:00
Sagar Vora
2fa641f86d fix: simplify erpnext.get_region 2023-04-20 05:17:30 -07:00
Sagar Vora
17ef3c964f fix: set frappe.flags.company to call regional code accurately 2023-04-20 05:17:30 -07:00
Rohit Waghchaure
c3b5dcb767 fix: stock entry type issue 2023-04-20 16:39:26 +05:30
Rohit Waghchaure
a90a5b4aa4 fix: removed depends on for the Employee Detail section 2023-04-20 16:01:05 +05:30
Sagar Sharma
76c4d9011f Merge pull request #34953 from s-aga-r/FIX-ISS-23-24-00209
fix: `PermissionError` in Work Order
2023-04-20 15:57:25 +05:30
Sagar Sharma
81653e4762 Merge branch 'develop' into FIX-ISS-23-24-00209 2023-04-20 15:46:01 +05:30
s-aga-r
8108b2de0a fix: PermissionError in Work Order 2023-04-20 15:41:37 +05:30
rohitwaghchaure
47b653db6d Merge pull request #34954 from SolufyPrivateLimited/fix-process_loss-in-bom
fix: process_loss_percentage in BOM
2023-04-20 15:00:15 +05:30
Nihantra Patel
b572bef71d fix: process_loss_percentage in BOM 2023-04-20 14:32:32 +05:30
Deepesh Garg
ea6eeace80 fix: filtering via batch no(#34950)
* fix: filtering via batch no
2023-04-20 12:48:44 +05:30
Sagar Sharma
6f26044163 Merge pull request #34912 from s-aga-r/FIX-INTERNAL-PR-GL-ENTRIES
fix: internal Purchase Receipt GL Entries
2023-04-20 11:35:17 +05:30
Sagar Sharma
e1f5a5adea Merge branch 'develop' into FIX-INTERNAL-PR-GL-ENTRIES 2023-04-20 11:00:22 +05:30
ruthra kumar
fc6486d87d Merge pull request #34922 from ruthra-kumar/refactor_payment_entry_ref_details
refactor: refactor set_missing_values and set_missing_ref_details in Payment Entry
2023-04-20 10:59:50 +05:30
ruthra kumar
df0682fa8c fix: broken set exchagne gain/loss btn broken in payment entry 2023-04-20 10:39:15 +05:30
Sagar Sharma
66723dc5db Merge branch 'develop' into FIX-INTERNAL-PR-GL-ENTRIES 2023-04-20 10:31:29 +05:30
rohitwaghchaure
ad662d38c7 Merge pull request #34937 from rohitwaghchaure/fixed-limit-issue-for-next-stock-reco
fix: add limit for get_next_stock_reco
2023-04-20 10:18:23 +05:30
s-aga-r
11c8503180 fix(test): test_backdated_stock_reco_cancellation_future_negative_stock 2023-04-20 09:59:11 +05:30
Rohit Waghchaure
fcfa8842a7 fix: limit stock reco issue 2023-04-20 09:48:15 +05:30
rohitwaghchaure
3df4edc5c5 Merge branch 'develop' into get_incoming_rate_v14_fix 2023-04-19 21:07:54 +05:30
rohitwaghchaure
dd238aa5b4 Merge pull request #34929 from rohitwaghchaure/fixed-stock-and-account-value-report
fix: Incorrect difference value in Stock and Account Value Comparison…
2023-04-19 21:07:25 +05:30
Rohit Waghchaure
a77182645f fix: Incorrect difference value in Stock and Account Value Comparison report 2023-04-19 20:35:14 +05:30
Sagar Sharma
c88beb76d6 Merge pull request #34901 from s-aga-r/FIX-ISS-23-24-00145
fix: add item-code filter for SCR supplied-items batch-no
2023-04-19 19:23:12 +05:30
Sagar Sharma
45c27e4e3d Merge branch 'develop' into FIX-ISS-23-24-00145 2023-04-19 19:22:42 +05:30
Sagar Sharma
daac4dc182 Merge pull request #34895 from s-aga-r/use-UnixTimestamp
fix: use `CombineDatetime` instead of `Timestamp` in QB queries
2023-04-19 19:19:40 +05:30
Sagar Sharma
6519514db4 Merge branch 'develop' into use-UnixTimestamp 2023-04-19 18:23:29 +05:30
Vishal Dhayagude
59f3fedbf7 fix: batch qty conversion factor issue fixed in pos transaction (#34917) 2023-04-19 15:57:28 +05:30
ruthra kumar
b7d6e30f63 refactor: update ref details for selected references
set_missing_ref_details can update only for selected references
2023-04-19 15:13:10 +05:30
s-aga-r
c86c543fbf test: add test case for internal PR GL Entries 2023-04-19 13:30:37 +05:30
Sagar Sharma
2c0e22c01d Merge branch 'develop' into use-UnixTimestamp 2023-04-19 12:57:20 +05:30
s-aga-r
e43bc38e05 refactor: rewrite get_stock_value_on() queries in QB 2023-04-19 12:05:17 +05:30
ruthra kumar
11cb2db3fe refactor: move set_missing_ref_detials out of set_missing_values 2023-04-19 11:54:08 +05:30
ruthra kumar
eaa5f1fd9d Merge pull request #34838 from ruthra-kumar/making_similar_ledger_entries_merging_optional
refactor: toggle merging similar ledger entries in JE
2023-04-19 09:48:44 +05:30
barredterra
98d51b6c7b fix: remove empty translations 2023-04-18 18:27:21 +02:00
barredterra
f0a3e61ee9 fix: remove excessive fourth column 2023-04-18 17:27:46 +02:00
s-aga-r
6fca9adcd4 fix: internal Purchase Receipt GL Entries 2023-04-18 18:38:28 +05:30
Hossein Yousefian
13d4f85923 get_incoming_rate_voucher_no_fix 2023-04-18 14:50:09 +03:30
Hossein Yousefian
bbd44e6e7e Merge branch 'frappe:develop' into get_incoming_rate_zero_in_rate_fix 2023-04-18 14:47:19 +03:30
barredterra
debc013728 fix: remove excessive fourth column 2023-04-18 12:23:54 +02:00
Sagar Sharma
a7c5b33c9f Merge pull request #34860 from s-aga-r/FIX-ISS-23-24-00171
fix: add items field label
2023-04-18 13:04:13 +05:30
s-aga-r
e91abbfbe3 fix: add item-code filter for SCR supplied-items batch-no 2023-04-18 13:03:47 +05:30
Sagar Sharma
d07d67a968 Merge branch 'develop' into use-UnixTimestamp 2023-04-18 12:56:25 +05:30
s-aga-r
91a398a191 fix: use CombineDatetime instead of Timestamp in QB queries 2023-04-18 12:55:16 +05:30
Sagar Sharma
a78b4bef0e Merge branch 'develop' into FIX-ISS-23-24-00171 2023-04-18 11:44:03 +05:30
ruthra kumar
3f537d30bd chore(patch): by default ledger entries of JE's will not be merged 2023-04-18 10:55:49 +05:30
ruthra kumar
a3e3fe149d refactor: checkbox to toggle merging of JE account heads 2023-04-18 08:59:33 +05:30
Ankush Menat
cc185bd2fe chore: update codeowners
[skip ci]
2023-04-18 08:40:24 +05:30
Ankush Menat
e4f152a416 fix: whitelist doc method
This should've been whitelisted, looks like it was missed out

closes https://github.com/frappe/erpnext/issues/34898
2023-04-18 08:24:22 +05:30
barredterra
aba87db6be fix: translation files
- remove leading "DocType: XXX"
- remove leading path and line number
- add trailing comma (three columns total)
2023-04-17 22:28:53 +02:00
MohsinAli
dd93ea067e fix: change discuss forum url (#34891)
[skip ci]
2023-04-17 17:00:52 +05:30
Deepesh Garg
534ea5ad21 fix: Add offers info to website item (#34873)
* fix: Add offers info to website item

* Revert "fix: Add offers info to website item"

This reverts commit 88b598edb6.

* fix: Add offer properties to website item
2023-04-17 16:35:22 +05:30
s-aga-r
a527221709 test: add test case for consumption of reserved stock 2023-04-17 15:33:55 +05:30
s-aga-r
2ed7d8a1fb fix: don't allow Stock Reconciliation for items having reserved stock 2023-04-17 15:33:55 +05:30
s-aga-r
dc9bb772cb refactor(test): use change_settings instead of update_stock_settings 2023-04-17 15:33:55 +05:30
s-aga-r
a87bb78d72 fix: don't allow to enable Stock Reservation and Negative Stock simultaneously 2023-04-17 15:33:55 +05:30
s-aga-r
73f16752a6 chore: conflicts 2023-04-17 15:33:55 +05:30
s-aga-r
866f98ac15 test: Stock Reservation for Serial and Batch Items 2023-04-17 15:33:46 +05:30
rohitwaghchaure
4f978a3cbd Merge pull request #34886 from rohitwaghchaure/fixed-stock-reco-test-case
fix: stock reconciliation test case
2023-04-17 15:21:49 +05:30
Rohit Waghchaure
6bccd8644e fix: stock reco test case 2023-04-17 14:22:35 +05:30
rohitwaghchaure
9fd8b8e53a Merge pull request #34851 from rohitwaghchaure/fixed-too-many-writes-error-in-stock-reco
fix: too many writes error while making backdated stock reconciliation
2023-04-17 12:01:36 +05:30
rohitwaghchaure
9f399f8741 Merge pull request #34882 from rohitwaghchaure/filter-to-hide-disabled-warehouses
fix: don't show disabled warehouses in the Warehouse Wise Stock Balance report
2023-04-17 12:00:57 +05:30
Rohit Waghchaure
9ceb1f6bda fix: don't show disabled warehouses in the Warehouse Wise Stock Balance report 2023-04-17 11:05:32 +05:30
Rohit Waghchaure
d9dd64b4d2 fix: linters issues 2023-04-16 23:25:51 +05:30
Sagar Sharma
db7b78328b Merge branch 'develop' into FIX-ISS-23-24-00171 2023-04-16 20:13:42 +05:30
Deepesh Garg
5c75894065 fix: Advance payment against payment terms (#34872) 2023-04-16 17:11:24 +05:30
Shariq Ansari
f27c921783 Merge pull request #34876 from shariquerik/selling-workspace-fix 2023-04-16 14:26:24 +05:30
rohitwaghchaure
634d526d15 Merge pull request #34852 from wojosc/patch-36
fix allowing rename of Lead
2023-04-16 14:18:49 +05:30
Shariq Ansari
5a4dd354c1 fix: selling workspace is not migrating properly 2023-04-16 13:10:42 +05:30
Hossein Yousefian
1d162ffb87 get_incoming_rate_zero_in_rate_fix 2023-04-16 11:03:16 +03:30
Sagar Sharma
68af588fcc Merge pull request #34858 from s-aga-r/FIX-ISS-23-24-00199
fix: unable to change `company` for manual `Serial No` entry
2023-04-15 12:10:13 +05:30
s-aga-r
c9418aab45 chore: add items field label 2023-04-14 16:57:14 +05:30
s-aga-r
fb3271c624 fix: unable to change company for manual Serial No entry 2023-04-14 15:59:35 +05:30
Devin Slauenwhite
51c4338661 fix(ux): don't throw error when company defaults aren't set (#34825)
* fix(ux): don't throw error when company defaults aren't set; instead prompt account input.

* fix: translate label and title
2023-04-14 15:20:51 +05:30
Rohit Waghchaure
7bfc8f1236 fix: too many writes error while making backdated stock reconciliation 2023-04-14 15:12:58 +05:30
Raffael Meyer
59f6b773cd feat: add german sales tax template (#34823)
Nullsteuersatz nach § 12 Abs. 3 UStG
2023-04-14 13:14:00 +05:30
Wolfram Schmidt
9d1cae01bd fix allowing rename of Lead
This is needed to consolidate data like merging leads together when duplicated appear.
2023-04-14 09:05:09 +02:00
Deepesh Garg
a7051cb9b5 fix: Don't use stale item details (#34847) 2023-04-14 09:59:42 +05:30
Deepesh Garg
66130493eb fix: Remove unnecessary checkbox from Accounts doctype (#34821) 2023-04-14 09:47:15 +05:30
Vishnu VS
194ed1842f fix: update workstation hour rate 2023-04-13 19:02:03 +05:30
s-aga-r
6c9e419fec fix: validation for Non-Stock item in Sales Order Reservation 2023-04-12 16:18:13 +05:30
s-aga-r
e65b6d47e4 fix: disable Stock Reservation by default 2023-04-12 15:12:56 +05:30
s-aga-r
f0acb2049b fix: don't allow to deliver/transfer reserved stock 2023-04-12 14:13:54 +05:30
s-aga-r
56097807b4 fix: Stock Reservation validation in Stock Settings 2023-04-12 13:58:11 +05:30
s-aga-r
e7491d117d test: add test case for Stock Reservation against SO 2023-04-11 17:25:13 +05:30
Saqib Ansari
7fabe62847 Merge pull request #34817 from frappe/nextchamp-saqib-patch-1
chore: update CODEOWNERS
2023-04-11 15:47:59 +05:30
Saqib Ansari
aa8b241d5a chore: update CODEOWNERS
[skip ci]
2023-04-11 15:46:47 +05:30
rohitwaghchaure
2f9856436e Merge pull request #34808 from rohitwaghchaure/fixed-reposting-issue-for-stock-reco
fix: reposting record not created for backdated stock reconciliation
2023-04-11 15:02:18 +05:30
Rohit Waghchaure
6851b5ba97 fix: reposting record not created for backdated stock reco 2023-04-11 14:35:33 +05:30
s-aga-r
51946c5528 chore: linter 2023-04-11 12:46:59 +05:30
Anand Baburajan
c957a5cd2e fix: provide filter by depreciable assets in fixed asset register (#34803) 2023-04-11 12:16:07 +05:30
s-aga-r
a14a6002e7 Merge branch 'develop' into stock-reservation 2023-04-11 10:00:39 +05:30
s-aga-r
efcb84cedf test: add test cases for SO 2023-04-11 09:11:51 +05:30
s-aga-r
bc3cb6bff6 fix: cancel SRE on SO cancel 2023-04-11 08:32:37 +05:30
s-aga-r
a918adaa33 test: add test cases for SRE 2023-04-11 08:29:59 +05:30
Raffael Meyer
934e1b4e6a fix: add german translation of "Partly Paid" (#34776) 2023-04-09 19:04:57 +05:30
Deepesh Garg
6f6928fa7b fix: Item tax validity comparison fixes (#34784)
fix: Item tax validity comparsion fixes
2023-04-09 09:38:13 +05:30
Sagar Sharma
02d5d43eb1 Merge pull request #34632 from s-aga-r/refactor-batch
refactor: rewrite `batch.py` queries in `QB`
2023-04-08 13:11:01 +05:30
Sagar Sharma
299fb2619f Merge branch 'develop' into refactor-batch 2023-04-08 11:15:08 +05:30
s-aga-r
4a9a5f03fc Merge branch 'develop' into refactor-batch 2023-04-08 11:06:27 +05:30
Sagar Sharma
ba553dba62 Merge pull request #34739 from resilient-tech/item-tax-override-remove
chore!: remove override to set item tax based on HSN code
2023-04-07 21:39:08 +05:30
Anand Baburajan
29e025c012 Merge pull request #34778 from AnandBaburajan/asset_value_adjust_get_depr_amt
fix: improper usage of get_depreciation_amount in asset_value_adjustment
2023-04-07 16:48:06 +05:30
Anand Baburajan
90dee8b663 Merge pull request #34735 from ihosseinu/asset_movement_translation_fix
'Make Asset Movement' button translation fix in asset_list.js
2023-04-07 15:30:26 +05:30
Anand Baburajan
edaa0bc3f7 Merge branch 'develop' into asset_value_adjust_get_depr_amt 2023-04-07 15:24:37 +05:30
anandbaburajan
984905109d fix: improper usage of get_depreciation_amount in asset_value_adjustment 2023-04-07 15:23:02 +05:30
Sagar Sharma
45291aaa43 Merge pull request #34760 from s-aga-r/FIX-ISS-22-23-06306
fix: validate `Received Qty` for Internal Purchase Receipt
2023-04-06 16:25:29 +05:30
Sagar Sharma
f7fb001126 Merge branch 'develop' into FIX-ISS-22-23-06306 2023-04-06 15:59:32 +05:30
s-aga-r
a575bd50ef test: add test cases for internal PR received qty 2023-04-06 15:26:19 +05:30
rohitwaghchaure
7d2d2dd0af Merge pull request #34768 from rohitwaghchaure/fixed-ux-issue
fix: UX for stock entry, bom and work order
2023-04-06 14:16:20 +05:30
Sagar Sharma
7934441f3c Merge pull request #34769 from s-aga-r/FIX-ISS-22-23-06397
fix: Subcontracting Receipt incorrect `status`
2023-04-06 13:56:23 +05:30
Sagar Sharma
cfd4da3e8a Merge branch 'develop' into FIX-ISS-22-23-06397 2023-04-06 13:23:39 +05:30
s-aga-r
a55b818119 fix: Subcontracting Receipt incorrect status 2023-04-06 13:20:33 +05:30
Rohit Waghchaure
82a136f991 fix: UX for stock entry, bom and work order 2023-04-06 12:51:32 +05:30
Deepesh Garg
91a26608ee fix: Unable to create payment request against purchase invoice (#34762) 2023-04-06 12:40:58 +05:30
s-aga-r
0d1df26b88 chore: add Delivery Note Item in Purchase Receipt Status Updater 2023-04-06 09:31:46 +05:30
s-aga-r
bc39dfab5d feat: add Received Qty field in Delivery Note Item 2023-04-06 09:29:44 +05:30
rohitwaghchaure
8503d581a5 Merge pull request #34743 from rohitwaghchaure/fix-incorrect-balance-qty
fix: incorrect stock balance quantity for batch item
2023-04-05 23:21:44 +05:30
s-aga-r
ac24d778e8 refactor: add Docstrings for functions 2023-04-05 19:48:15 +05:30
Lucky-Tsuma
9bf87d708e fix: payment entry is already created on posawesome. (#34712) 2023-04-05 13:52:00 +05:30
Deepesh Garg
56f5078357 fix: Shop by category fixes (#34688)
* fix: Shop by category fixes

* chore: Update tests
2023-04-05 12:43:32 +05:30
Ritwik Puri
f193393f57 fix!: require sender and message for contact us page (#34707)
* fix: require sender and message for contact us page

* refactor: dont override frappe.send_message from client side

used override_whitelisted_method hook for the same
2023-04-05 12:04:36 +05:30
Deepesh Garg
fd3fb64aa3 feat: Auto allocate advance payments only against orders (#34727)
feat: Auto allocate advance payments only againt orders
2023-04-05 12:02:44 +05:30
Anand Baburajan
869289a6e4 Merge pull request #34745 from frappe/mergify/bp/develop/pr-34737
fix: don't include cancelled JVs in assdeprledger report (backport #34737)
2023-04-05 11:59:52 +05:30
Raffael Meyer
e6a9b6ee95 feat: remove deprecated get_customer_list (#34624)
feat: remove deprecated method

get_customer_list
2023-04-05 11:56:15 +05:30
Anand Baburajan
5cc3c08059 fix: asset monthly WDV and DD schedule and refactor [develop] (#34646)
* fix: monthly wdv and dd schedule

* chore: minor rename

* chore: fix tests
2023-04-05 11:46:31 +05:30
anandbaburajan
1101b7bfdf fix: don't include cancelled JVs in assdeprledger report
(cherry picked from commit 3896d41e95)
2023-04-05 06:04:43 +00:00
Rohit Waghchaure
ef4bd77196 fix: incorrect stock balance quantity for batch item 2023-04-05 00:02:45 +05:30
Sagar Vora
9c66ebb108 chore!: remove override to set item tax based on HSN code 2023-04-04 18:02:55 +05:30
Hossein Yousefian
b70615ef18 'Make Asset Movement' button translation fix 2023-04-04 14:49:43 +03:30
rohitwaghchaure
12325cb685 Merge pull request #31271 from dj12djdjs/fix-reserve-qty
fix(stock): don't reserve qty on sales return.
2023-04-04 06:21:30 +05:30
rohitwaghchaure
682730a498 Merge pull request #34715 from rohitwaghchaure/fixed-bom-update-log
fix: bom update log not working for large batch size
2023-04-03 15:49:25 +05:30
Sagar Sharma
5f2874743b Merge pull request #34713 from s-aga-r/FIX-ISS-22-23-06369
fix: consider qty field precision
2023-04-03 15:36:19 +05:30
Rohit Waghchaure
d56070301c fix: bom update log not working for large batch size 2023-04-03 14:47:58 +05:30
Sagar Sharma
4571bd58d2 Merge branch 'develop' into FIX-ISS-22-23-06369 2023-04-03 14:26:09 +05:30
s-aga-r
6ec7590c21 fix: consider qty field precision 2023-04-03 14:08:11 +05:30
ruthra kumar
1eefd517d1 Merge pull request #34694 from ruthra-kumar/recalculate_difference_on_allocation_change
fix(ui): recalculate difference amount on allocation change
2023-04-03 10:03:01 +05:30
s-aga-r
38e9367184 fix: re-reserve stock on SO Update Items 2023-04-02 21:24:59 +05:30
s-aga-r
d5f0a7fcbb refactor(minor): stock reservation entry 2023-04-02 19:23:22 +05:30
Deepesh Garg
4c61ee30bb fix: Multiple issues in purchase invoice submission (#34600)
* fix: Multiple issues in purchase invoice submission

* fix: Base grand total calculation

* chore: Calculate base grand total separately only in multi currency docs

* fix: Add gl entry for round off
2023-04-02 09:35:27 +05:30
Kitti U. @ Ecosoft
74b29eb5e2 fix: Bank clearance for case loan (disburstment/repayment) (#34586) 2023-04-01 18:50:30 +05:30
Deepesh Garg
1e3eb4deed Merge pull request #34287 from frappe/early-payment-loss
fix: Allocate tax loss to tax account head on early payment discount
2023-04-01 18:49:02 +05:30
Sagar Sharma
7c7cfc4373 Merge pull request #34656 from s-aga-r/FIX-33830
fix: BOM Update Cost, when no actual qty
2023-04-01 16:24:01 +05:30
s-aga-r
8f3d5d24e1 chore: notify user on Reservation and Unreservation of Stock 2023-04-01 16:21:50 +05:30
s-aga-r
ee322c4904 fix(ux): Allow Partial Reservation depends on Enable Stock Reservation 2023-04-01 15:55:10 +05:30
ruthra kumar
32a4ca6b6c fix: recalculate difference amount on allocation change 2023-04-01 09:17:33 +05:30
s-aga-r
ef34f703d4 fix(ux): don't show Stock Reservation btn if Stock Reservation is disabled 2023-03-31 22:08:12 +05:30
s-aga-r
632f27b10d fix(ux): Reserve Stock and Reserved Stock Qty in SO Item 2023-03-31 21:58:21 +05:30
s-aga-r
de1492759d feat: add option to reserve stock in SO 2023-03-31 21:42:13 +05:30
s-aga-r
0ae400c986 feat: add option to unreserve stock in SO 2023-03-31 15:38:16 +05:30
Sagar Sharma
2c2b5a5b6e Merge branch 'develop' into FIX-33830 2023-03-31 14:14:17 +05:30
ruthra kumar
770640f4e1 Merge pull request #34679 from ruthra-kumar/fix_credit_note_with_positive_total
fix: enclose ternary operator in parentheses
2023-03-31 13:31:16 +05:30
s-aga-r
26569b2162 fix: Stock Reservation validation for SO 2023-03-31 13:12:19 +05:30
s-aga-r
81fe5cfd72 chore: update Reserve Stock label to Reserve Stock on Submit in SO 2023-03-31 13:06:30 +05:30
s-aga-r
4d8ae41553 chore: make Reserve Stock on Sales Order Submission disabled by default 2023-03-31 12:50:13 +05:30
Sagar Sharma
b4ace345f9 Merge branch 'develop' into FIX-33830 2023-03-31 12:35:45 +05:30
Sagar Sharma
e56d40f48a Merge pull request #34677 from s-aga-r/FIX-34240
chore: make `Production Plan Item Reference` table hidden in Production Plan
2023-03-31 12:34:59 +05:30
Sagar Sharma
d0d3961a1e Merge branch 'develop' into FIX-34240 2023-03-31 12:34:27 +05:30
s-aga-r
06d1bc4d12 Revert "chore: add SRE ref in DN dashboard"
This reverts commit 15cb99290c.
2023-03-31 12:20:52 +05:30
s-aga-r
2d3997b2d7 refactor: remove Against Stock Reservation Entry field from DN Item 2023-03-31 12:16:59 +05:30
ruthra kumar
986daa6578 fix: enclose ternary operator in parentheses 2023-03-31 12:09:57 +05:30
Deepesh Garg
576575c227 fix: Column value mismatch in COA blank template (#34658) 2023-03-31 11:10:50 +05:30
s-aga-r
706be2a415 chore: make Production Plan Item Reference table hidden in Production Plan 2023-03-31 10:32:49 +05:30
Deepesh Garg
7c42b72ee7 fix: Total debit and credit while importing via Data Import (#34659) 2023-03-30 17:28:19 +05:30
rohitwaghchaure
edb0666b2c Merge branch 'develop' into fix-reserve-qty 2023-03-30 17:26:32 +05:30
rohitwaghchaure
c4a0842a4f Merge pull request #34636 from rohitwaghchaure/posting-time-issue
fix: posting time issue
2023-03-30 17:25:47 +05:30
rohitwaghchaure
06eac67796 Merge pull request #34664 from rohitwaghchaure/fixed-incorrect-balance-qty-stock-ledger
fix: incorrect balance qty in the stock ledger report
2023-03-30 17:25:35 +05:30
Richard Case
ddb17a8880 fix: plaid log_error syntax issue (#34642) 2023-03-30 16:45:56 +05:30
s-aga-r
1a84a0c411 fix: DN Item group warehouse validation against SRE 2023-03-30 16:42:27 +05:30
Anand Baburajan
d999dea3e4 chore: improve asset depr posting failure msg (#34661)
* chore: improve asset depr posting error msg

* chore: add period

* chore: improve msg
2023-03-30 16:38:37 +05:30
Rohit Waghchaure
345e6facbe fix: posting time issue 2023-03-30 16:34:34 +05:30
s-aga-r
e286d05904 fix: SRE Available Qty to Reserve for Group Warehouse 2023-03-30 16:26:42 +05:30
Rohit Waghchaure
cbdaab940d fix: incorrect balance qty in the stock ledger report 2023-03-30 16:20:42 +05:30
Anand Baburajan
a7a45fbe59 Merge pull request #34660 from AnandBaburajan/asset_improvements_30_mar_develop
chore: auto fill asset name and available for use date
2023-03-30 16:07:59 +05:30
anandbaburajan
af3e807607 chore: auto fill asset name and available for use date 2023-03-30 15:28:59 +05:30
Sagar Sharma
b6c0a675f9 Merge branch 'develop' into FIX-33830 2023-03-30 13:49:41 +05:30
s-aga-r
a4112c75c5 fix: BOM Update Cost, when no actual qty 2023-03-30 13:46:50 +05:30
rohitwaghchaure
448afa2b7c Merge pull request #34648 from rohitwaghchaure/fixed-serial-no-qty-issue-in-stock-reco
fix: serial no with zero quantity issue in stock reco
2023-03-30 13:04:48 +05:30
Anand Baburajan
0ac81e3793 Merge pull request #34649 from AnandBaburajan/asset_value_adjustment_asset_name
fix: incorrect arg name in asset value adjustment
2023-03-30 13:03:18 +05:30
Anand Baburajan
33ff1b5a72 Merge branch 'develop' into asset_value_adjustment_asset_name 2023-03-30 12:53:06 +05:30
anandbaburajan
2b0470d1f5 fix: incorrect arg name in asset value adjustment 2023-03-30 12:50:33 +05:30
Rohit Waghchaure
17131e5a02 fix: serial no with zero quantity issue in stock reco 2023-03-30 11:47:32 +05:30
Komal-Saraf0609
ad11934d39 fix: enabling lead even after "Opportunity" created against it (#34627)
* fix: enabling lead even after "Opportunity" created against it

* chore: Linting Issues

---------

Co-authored-by: Komal Saraf <komal@frappe.io>
Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-03-30 08:03:55 +05:30
s-aga-r
72e32f1ae4 refactor: remove Posting Date and Posting Time columns from SRE 2023-03-29 18:42:44 +05:30
s-aga-r
2522198129 Revert "chore: add fields Serial No and Batch No in SRE"
This reverts commit 48108b5b41.
2023-03-29 18:33:03 +05:30
s-aga-r
6b24551672 Revert "chore: add Stock Reservation Qty column in Stock Projected Qty Report"
This reverts commit 3d75e3f434.
2023-03-29 18:33:03 +05:30
s-aga-r
3fcaa21110 refactor(minor): stock_reservation_entry.py 2023-03-29 18:33:01 +05:30
Anand Baburajan
7c5720ddb3 Merge pull request #34641 from frappe/mergify/bp/develop/pr-34607
Asset maintenance task add dropdown "3 Yearly" (backport #34607)
2023-03-29 18:15:17 +05:30
Bevan Tony Medrano
ddc3050e99 Asset maintenance task add dropdown "3 Yearly" (#34607)
* feat(asset_maintenance.json):Add 3 yearly in periodicity dropdown

* add server side implications for 3 yearly

(cherry picked from commit 625b8e8005)
2023-03-29 12:16:03 +00:00
Raffael Meyer
f5453adf4d fix: switch to supported update_linked_doctypes (#34625) 2023-03-29 16:59:10 +05:30
Komal-Saraf0609
d0660ad222 fix: lost opportunity report issue (#34626)
* fix: lost opportunity report issue

* chore: Linting Issues

---------

Co-authored-by: Komal Saraf <komal@frappe.io>
Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-03-29 16:51:18 +05:30
s-aga-r
517b5f8567 refactor: rewrite batch.py queries in QB 2023-03-29 14:02:09 +05:30
Sagar Sharma
867d898304 fix: zero rm-cost for batch rm item in SCR (#34616)
fix: `0` rm-cost for batch rm item in SCR
2023-03-28 18:45:16 +05:30
rohitwaghchaure
738dd57904 Merge pull request #34461 from s-aga-r/FIX-ISS-22-23-05936
fix: incorrect `Opening Value` in `Stock Balance` report
2023-03-28 17:40:25 +05:30
akiratfli
07c9b99072 fix: bad strings format for update-translations (#34592)
Co-authored-by: justin.li <justin.li@lungteh.com>
2023-03-28 17:20:54 +05:30
ruthra kumar
7c13533f30 Merge pull request #34608 from ruthra-kumar/reconciliation_debit_credit_mismatch
chore: removing redundant validation
2023-03-28 16:54:37 +05:30
Vishal Dhayagude
7aafc90d58 fix: Tax Category not able to set hence it calculating zero tax for item whoes tax template set (#34525)
* fix: Tax Category not able to set hence it calculating zero tax for item whoes tax template set

* fix: minor change added
2023-03-28 16:48:03 +05:30
Devin Slauenwhite
393bc25e2d fix: don't get zero value entries for exchange rate calculation (#34475)
* fix: multiply None by float

* chore: remove debug
2023-03-28 16:34:24 +05:30
Deepesh Garg
50c1172f29 fix: Party Name in SOA print when viewed from Customer/Supplier master (#34597)
fix: Party Name in SOA print when viewd from Customer/Supplier master
2023-03-28 15:36:16 +05:30
Deepesh Garg
12ad2aa2e5 fix: Percentage billing in Sales Order (#34606) 2023-03-28 15:33:59 +05:30
Marica
dae40dfbb4 Merge branch 'develop' into early-payment-loss 2023-03-28 15:01:28 +05:30
ruthra kumar
d52f7e2820 fix: removing redundant validation 2023-03-28 13:44:23 +05:30
s-aga-r
7d0bc0914d Merge branch 'develop' into stock-reservation 2023-03-28 12:25:17 +05:30
s-aga-r
beb425e1ff chore: add Stock Reservation Qty column in Stock Balance Report 2023-03-27 21:03:35 +05:30
Devin Slauenwhite
3c553b0938 feat: don't reserve qty on sales return 2023-03-27 10:37:54 -04:00
Devin Slauenwhite
17f8080168 chore: revert get_reserve_qty method 2023-03-27 10:37:04 -04:00
s-aga-r
3d75e3f434 chore: add Stock Reservation Qty column in Stock Projected Qty Report 2023-03-27 19:12:08 +05:30
marination
216a46bd66 feat: Make Tax loss booking optional
- Checkbox in Accounts Settings
- Apply checkbox in PE deductions setting logic
- Adjust tests
2023-03-27 16:11:00 +05:30
s-aga-r
00ac49f81b refactor(minor): SRE functions 2023-03-27 12:18:40 +05:30
s-aga-r
22a9c8ad55 fix(ux): SRE filters in DN Items 2023-03-27 11:07:24 +05:30
s-aga-r
b95a49e4c2 fix: validate DN against SRE 2023-03-27 10:46:07 +05:30
s-aga-r
3602d1909e fix: map DN items based on SRE 2023-03-26 17:33:01 +05:30
s-aga-r
15cb99290c chore: add SRE ref in DN dashboard 2023-03-26 16:53:31 +05:30
s-aga-r
cdc625806d chore: add field Against Stock Reservation Entry in DN Item 2023-03-26 16:53:28 +05:30
s-aga-r
744166da73 fix(ux): unable to uncheck Reserve Stock button in SO 2023-03-26 12:14:00 +05:30
s-aga-r
9652cb8de5 chore: create SRE on SO submission 2023-03-25 15:50:00 +05:30
=
1142e69d1a Merge branch 'develop' into fix-reserve-qty
# Conflicts:
#	erpnext/selling/doctype/selling_settings/selling_settings.json
2023-03-24 23:50:50 -04:00
s-aga-r
be9fa8c047 fix: don't allow to disable Stock Reservation if SRE exists 2023-03-24 21:39:36 +05:30
s-aga-r
48108b5b41 chore: add fields Serial No and Batch No in SRE 2023-03-24 16:23:38 +05:30
s-aga-r
7b6e4d44b7 chore: remove Valuation Rate field from SRE 2023-03-24 16:09:38 +05:30
ruthra kumar
f7780cdb58 refactor: additional filters and columns in Payment Ledger report (#34577)
1. 'Party type' and 'Party' filters have been added
2. checkbox to include Amount in Acccount Currency
3. Grouping vouchers on Party
4. Replaced Company with Posting Date
2023-03-24 12:25:03 +05:30
Raffael Meyer
8c7fa5712b feat: deprecate get_customer_list (#34563) 2023-03-24 12:13:53 +05:30
Shram Kadia
0cd870fc29 fix: get batch_no. for item automatically (#34473)
* fix: default pos conversion factor set to 1

* fix:get-batch-no-of-item-automatically
2023-03-24 12:05:26 +05:30
Nabin Hait
282a0ee2ce Merge pull request #34257 from deepeshgarg007/opening_entry
feat: Closing balance for period closing and reporting
2023-03-24 11:59:00 +05:30
rohitwaghchaure
980cca1772 Merge pull request #34573 from rohitwaghchaure/timer-buttons-not-working
fix: Time buttons not working in the job card
2023-03-23 22:35:43 +05:30
Rohit Waghchaure
34c190b7d6 fix: Time button not working in the job card 2023-03-23 22:32:11 +05:30
Anand Baburajan
e6b0196493 fix: recalculate wdv rate after asset repair [develop] (#34570)
fix: recalculate wdv rate after asset repair
2023-03-23 21:10:22 +05:30
s-aga-r
c80ce99972 feat: configuration to allow partial reservation 2023-03-23 19:53:17 +05:30
s-aga-r
ee074883bb chore: add Partially Reserved status in SRE 2023-03-23 19:50:34 +05:30
s-aga-r
4ad55382cf chore: add field Voucher Qty in SRE 2023-03-23 19:37:57 +05:30
Deepesh Garg
87108be11a fix: Sales person variance report without item group (#34552)
fix: Sales person variance report witout item group
2023-03-23 19:19:46 +05:30
Deepesh Garg
8ce1da111e chore: Improve validation message 2023-03-23 19:14:12 +05:30
Deepesh Garg
f8cff09129 fix: CS financial statement param 2023-03-23 19:12:42 +05:30
Deepesh Garg
b7dcf27b01 fix: Partial trial balance view 2023-03-23 19:06:07 +05:30
Deepesh Garg
30eb6c8512 fix: Validation for cancelation 2023-03-23 19:05:25 +05:30
Deepesh Garg
3fd95200da chore: Fix Typo 2023-03-23 19:04:48 +05:30
Deepesh Garg
528ab503f2 fix: Don't validate if no GL Entry exists 2023-03-23 15:32:24 +05:30
s-aga-r
1ccdf588e2 fix(ux): Reserve Stock button behaviour in SO 2023-03-23 13:34:40 +05:30
s-aga-r
f8c477ca5c chore: rename status from Submitted to Reserved 2023-03-23 13:05:43 +05:30
s-aga-r
fd746288f8 chore: add field Available Qty to Reserve in SRE 2023-03-23 13:05:41 +05:30
Raffael Meyer
f7bf1b8a0c fix: unset address and contact on trash (#34495)
* fix(Customer): unset address and contact on trash

* fix(Supplier): unset address and contact on trash

---------

Co-authored-by: Sagar Sharma <sagarsharma.s312@gmail.com>
2023-03-23 11:52:32 +05:30
Shariq Ansari
829bc6a51f Merge pull request #34547 from shariquerik/crm-comments-overlap-fix 2023-03-22 12:02:10 +05:30
Shariq Ansari
24a0833980 Merge branch 'develop' into crm-comments-overlap-fix 2023-03-22 11:40:58 +05:30
Shariq Ansari
76cea7dd6a fix: Note username overlapping with note content(CRM) 2023-03-22 11:28:58 +05:30
s-aga-r
30d566a787 fix: update Reserved Qty in SO Item on SRE cancel 2023-03-21 23:49:01 +05:30
s-aga-r
c2ba8b1b54 chore: make SRE a submittable DocType 2023-03-21 20:16:07 +05:30
Anand Baburajan
6d6a7bcb50 fix: incorrect depr schedules after asset repair [develop] (#34544)
* fix: backport missing changes from #30838

* fix: incorrect schedule after repair
2023-03-21 20:07:27 +05:30
Deepesh Garg
fa991b2dcf Merge branch 'develop' of https://github.com/frappe/erpnext into opening_entry 2023-03-21 17:00:08 +05:30
Deepesh Garg
f9397a87ac fix: Ignore opening entries if PCV posted 2023-03-21 16:59:22 +05:30
Richard Case
d8e73b63f3 fix: remove non-maintained Tax Detail report and missing workspace links (#34192)
* fix: remove non-maintained Tax Detail report and missing workspace links

* patch: delete report "Tax Detail"

---------

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2023-03-21 16:23:27 +05:30
Raffael Meyer
79911734e9 fix: translations and UX in alternative item mapping (#34433)
* fix: disable deletion in alternative item mapping

* feat: german translations

* fix: make string translatable

---------

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-03-21 16:20:11 +05:30
Raffael Meyer
0df3a1a3af fix: remove unused translation (#34519) 2023-03-21 16:18:45 +05:30
Shram Kadia
08fc686513 fix: default pos conversion factor set to 1 (#34437) 2023-03-21 15:51:18 +05:30
Raffael Meyer
59c2e7ec3e fix: german translations (#34312)
fix: some german translations
2023-03-21 15:48:27 +05:30
Vishal Dhayagude
6966fa4d88 fix: POS not picking up pos profile company address instead fetch any random company address (#34521) 2023-03-21 15:43:57 +05:30
Deepesh Garg
ee6c107d58 fix(client): Amount calculation for 0 qty debit notes (#34455)
fix(client): Amount calculaton for 0 qty debit notes

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
2023-03-21 15:38:39 +05:30
ruthra kumar
2d19cee713 Merge pull request #34501 from ruthra-kumar/incorrect_currency_symbol_for_bank_accounts_in_reconciliation_tool
refactor(bank reconciliation tool): currency symbol fix and concurrent usage
2023-03-21 15:30:50 +05:30
rohitwaghchaure
af5f59e856 Merge pull request #34528 from rohitwaghchaure/no-stock-still-option-to-add-in-cart
fix: E-commerce issue with Item Variants
2023-03-21 14:46:20 +05:30
Rohit Waghchaure
aaa4d1eb55 fix: E-commerce issue with Item Variants 2023-03-21 14:44:12 +05:30
s-aga-r
f858f657a0 feat: add Stock Reservation Entry ref in SO connections 2023-03-21 13:28:31 +05:30
s-aga-r
50de868285 chore: add Stock Reserved Qty field in SO Item 2023-03-21 13:17:58 +05:30
Marica
c5da7f5fb1 Merge branch 'develop' into early-payment-loss 2023-03-21 11:40:30 +05:30
s-aga-r
0700063379 chore: add Reserve Stock check field in Sales Order 2023-03-20 23:55:33 +05:30
s-aga-r
1b7fb6d7e7 chore: make Stock UOM required in SRE 2023-03-20 22:41:22 +05:30
s-aga-r
4848a054a8 chore: make Submitted default status for Stock Reservation Entry 2023-03-20 22:40:06 +05:30
s-aga-r
2946de40d8 fix: make Project and Is Cancelled field read-only in SRE 2023-03-20 21:18:37 +05:30
s-aga-r
0d1332942c feat: add Status and Delivered Qty fields in Stock Reservation Entry 2023-03-20 19:01:37 +05:30
Ankush Menat
109a9f1390 perf: index against_sales_invoice field on DN items (#34509)
This is used on Sales invoice dashboard and takes a lot of time to load
as db size increases.

Results:

Before: ~10-20 seconds to load dashboard
After: few milliseconds because of index

[skip ci]
2023-03-20 14:46:26 +05:30
s-aga-r
da1455198e chore: field validation for Stock Reservation Entry 2023-03-20 13:42:11 +05:30
s-aga-r
7eb2075265 feat: add settings for Stock Reservation in Stock Settings 2023-03-20 11:45:35 +05:30
s-aga-r
085d9ce004 feat: add DocType Stock Reservation Entry 2023-03-20 11:20:30 +05:30
Sagar Sharma
4c35a37eaa Merge branch 'develop' into FIX-ISS-22-23-05936 2023-03-20 10:28:10 +05:30
Deepesh Garg
44053db010 chore: Remove unnecessary list comprehension 2023-03-19 19:46:01 +05:30
Deepesh Garg
fc86a8568f fix: Supplier RFQ email link (#34338) 2023-03-19 18:09:18 +05:30
Raffael Meyer
d791dc11a3 fix: patch depends on Currency Exchange Settings (#34494) 2023-03-19 18:05:12 +05:30
ruthra kumar
1eea585d29 refactor: allow for concurrent use of reconciliation tool
1. set default filter dates a period of one month from current date
2023-03-19 14:20:03 +05:30
ruthra kumar
2d14d92b32 fix: incorrect currency symbol in Bank Reconciliation tool 2023-03-19 12:47:29 +05:30
Deepesh Garg
0aadb680eb chore: Add missing validations 2023-03-19 12:46:42 +05:30
Deepesh Garg
00fe3042b2 chore: Simplify query 2023-03-18 20:05:43 +05:30
Deepesh Garg
7f11373b58 fix: Account sub query 2023-03-17 16:59:23 +05:30
Deepesh Garg
d11a64ddcb Merge branch 'develop' of https://github.com/frappe/erpnext into opening_entry 2023-03-17 16:50:49 +05:30
Sagar Sharma
a07a5572ea Merge branch 'develop' into FIX-ISS-22-23-05936 2023-03-17 16:18:54 +05:30
Danny
ca10e2bb9f fix: bad strings format for command get-untraslated (#34361)
* fix: bad string foramt

* fix: bad string format

* fix: pre-commit format

---------

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
2023-03-17 16:13:32 +05:30
Sagar Sharma
2ac079210d Merge pull request #34440 from s-aga-r/FIX-34354
chore: `Allow Zero Valuation Rate` msg in SE
2023-03-17 16:02:52 +05:30
Sagar Sharma
f2c78163bf Merge branch 'develop' into FIX-34354 2023-03-17 15:58:46 +05:30
Deepesh Garg
d8ece86463 fix: Update account number from parent company (#34474) 2023-03-17 15:55:11 +05:30
Deepesh Garg
7b630217bd fix: Multiple accounting dimension filtering in AR/AP reports (#34464)
Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
2023-03-17 15:51:33 +05:30
Deepesh Garg
be723bb9d4 chore: Update user manual link (#34478) 2023-03-17 15:39:33 +05:30
ruthra kumar
6b0dc62681 Merge pull request #34456 from ruthra-kumar/gp_return_invoice_issue
fix: Gross Profit reports Invoices with -ve qty for Invoices with Cr Notes
2023-03-17 15:26:41 +05:30
Sagar Sharma
0753aa5ab7 Merge branch 'develop' into FIX-34354 2023-03-17 15:16:41 +05:30
Sagar Sharma
3fb64cacfc Merge branch 'develop' into FIX-ISS-22-23-05936 2023-03-17 15:03:44 +05:30
ruthra kumar
6e0f1c6ad6 Merge pull request #34466 from ruthra-kumar/difference_amount_issue_while_reconciling
fix: unwanted difference amt while reconciling vouchers from base currency account
2023-03-17 14:51:41 +05:30
ruthra kumar
cc61daeec4 test: Gross Profit report output for Cr notes
2 New test cases added.
1. Standalone Cr notes will be reported as normal Invoices
2. Cr notes against an Invoice will not overallocate qty if there are
multiple instances of same item
2023-03-17 14:48:57 +05:30
ruthra kumar
d0715a82eb refactor: Ignore linked Cr Notes in Report output 2023-03-17 14:48:57 +05:30
ruthra kumar
e2f19c6a14 fix: Overallocation of 'qty' from Cr Notes to Parent Invoice
Cr Notes 'qty' are overallocated to parent invoice, when there are
mulitple instances of same item in Invoice.
2023-03-17 14:48:57 +05:30
ruthra kumar
ec075122b6 refactor: difference amt validation for same currency accounts 2023-03-17 14:14:17 +05:30
ruthra kumar
861387f164 test: difference amount should not be calculated for base currency 2023-03-17 14:14:17 +05:30
ruthra kumar
48fae0c1ce fix: difference amount calculation for company currency accounts 2023-03-17 14:14:17 +05:30
Sagar Sharma
db1f2d6279 Merge branch 'develop' into FIX-ISS-22-23-05936 2023-03-17 13:54:13 +05:30
s-aga-r
b04a101c11 fix: incorrect Opening Value in Stock Balance report 2023-03-17 13:53:49 +05:30
rohitwaghchaure
1d767d58f2 Merge pull request #34279 from s-aga-r/fix-22-23-05686
fix: `Blanket Order`
2023-03-17 10:14:37 +05:30
rohitwaghchaure
558db13040 Merge branch 'develop' into fix-22-23-05686 2023-03-17 08:57:37 +05:30
Anand Baburajan
563ee92043 Merge branch 'develop' into FIX-34354 2023-03-16 18:22:13 +05:30
Anand Baburajan
b6b8392413 fix: refactor asset depr schedule and remove unnecessary depr method (#34434)
* fix: remove depr method from depr schedule and refactor assetdeprsch

* chore: use assetdeprsch's depr method, not deprschedule's

* fix: use default 0 value for NDB and OAD

* chore: fix rounded numbers

* chore: correct rounding in test_website_item_price_for_logged_in_user
2023-03-16 18:18:47 +05:30
mergify[bot]
bd2dd7dfac ci: use version specific payments repo (backport #34468) (#34470)
ci: use version specific payments repo (#34468)

ci: use version-14 branch of payments repo for v14 erpnext
(cherry picked from commit befd1a0f91)

Co-authored-by: Ritwik Puri <ritwikpuri5678@gmail.com>
2023-03-16 16:20:21 +05:30
Sagar Sharma
357d4994e4 Merge branch 'develop' into fix-22-23-05686 2023-03-14 20:59:38 +05:30
Sagar Sharma
ea269c6a1c Merge branch 'develop' into FIX-34354 2023-03-14 20:59:27 +05:30
Ankush Menat
f1752fcd7a Merge pull request #34116 from prateekkaramchandani/develop
fix: use max function to get default company address
2023-03-14 19:38:26 +05:30
Ankush Menat
e0042972c8 test: add test for primary address sorting 2023-03-14 18:50:19 +05:30
Sagar Sharma
e9f5ea6ede Merge pull request #34415 from s-aga-r/FIX-ISS-22-23-05720
fix: operation time for multi-level BOM in WO
2023-03-14 18:47:40 +05:30
Ankush Menat
55489d0056 Merge branch 'develop' into prateekkaramchandani/develop 2023-03-14 18:39:06 +05:30
Sagar Sharma
e0b288fbf0 Merge branch 'develop' into FIX-34354 2023-03-14 18:19:38 +05:30
Sagar Sharma
258242f8d7 Merge branch 'develop' into FIX-ISS-22-23-05720 2023-03-14 18:17:48 +05:30
Ankush Menat
f95ad039e4 test: add timeout to all BOM related tests (#34446)
* Revert "chore: remove failing test (#34444)"

This reverts commit b89ecd482d.

* test: add timeout to bom tests
2023-03-14 18:10:17 +05:30
Deepesh Garg
b89ecd482d chore: remove failing test (#34444) 2023-03-14 15:53:03 +05:30
Johannes Obermeier
70c78d0d67 fix: incorrect EAN validation, EAN can be an EAN8, EAN12 or EAN13 code (#34250)
Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-03-14 15:27:05 +05:30
s-aga-r
22ad9a1903 chore: Allow Zero Valuation Rate msg in SE 2023-03-14 14:33:03 +05:30
marination
d6d0163514 fix: Provision to apply early payment discount if payment is recorded late
- Party could have paid on time but payment is recorded late
- Prompt for reference date so that discount is applied while mapping
- Prompt only if discount in payment schedule of valid doctypes
- test: Reference date and impact on PE
- `make_payment_entry` (JS) must be able to access `this`
2023-03-14 14:22:39 +05:30
Sagar Sharma
0dbf4557db Merge branch 'develop' into FIX-ISS-22-23-05720 2023-03-14 13:19:58 +05:30
Sagar Sharma
185a8910d2 Merge branch 'develop' into fix-22-23-05686 2023-03-14 13:19:46 +05:30
Anand Baburajan
fe672aa9b1 Merge pull request #34392 from AnandBaburajan/patch_assdeprsch_gpa_ndb
fix: add missing patch for new fields added in #34214
2023-03-14 12:18:29 +05:30
Sagar Sharma
6c88fb7a8d Merge branch 'develop' into fix-22-23-05686 2023-03-14 11:44:39 +05:30
Sagar Sharma
48a88b7064 Merge branch 'develop' into FIX-ISS-22-23-05720 2023-03-14 11:44:33 +05:30
Anand Baburajan
72e9c05f46 Merge branch 'develop' into patch_assdeprsch_gpa_ndb 2023-03-13 21:31:57 +05:30
Deepesh Garg
c6999fc687 fix: Total row in trail balance report (#34395)
* fix: Total row in trail balance report

* fix: Calculate total after preparing opening and closing
2023-03-13 21:18:30 +05:30
Deepesh Garg
91f7b0bbd6 Merge branch 'develop' of https://github.com/frappe/erpnext into opening_entry 2023-03-13 20:52:48 +05:30
Deepesh Garg
76775a3e49 fix: Update patch 2023-03-13 20:51:35 +05:30
Deepesh Garg
492e994c22 Merge branch 'develop' into patch_assdeprsch_gpa_ndb 2023-03-13 19:37:55 +05:30
Deepesh Garg
fa776d2987 fix: Use customer name instead of name(id) in PSOA (#34412) 2023-03-13 19:37:09 +05:30
Deepesh Garg
d8e54a21fb test: Update values in Sales Invoice tests (#34419) 2023-03-13 19:34:15 +05:30
Sagar Vora
5c06620f97 fix: set tax category from address before executing get_regional_address_details (#34372) 2023-03-13 19:32:50 +05:30
HENRY Florian
d267111e13 chore: fix french translation (#34381)
chore: update french translation
2023-03-13 19:03:16 +05:30
Ernesto Ruiz
796ad01b87 fix: Add translate function to Delayed Tasks Summary Report (#34411)
fix: Add translate function to Delayed Tasks Summary Report
2023-03-13 19:02:34 +05:30
Deepesh Garg
c8cc3fc65f chore: Move source and campaign to additional info section (#34414) 2023-03-13 18:37:19 +05:30
Deepesh Garg
4416ddc4af fix: Linked invoice cancellation issue via timesheet (#34337) 2023-03-13 18:36:43 +05:30
Sagar Sharma
4a05f3736f Merge branch 'develop' into FIX-ISS-22-23-05720 2023-03-13 17:50:09 +05:30
s-aga-r
66f650061d test: add test cases for Over Order Allowance against Blanket Order 2023-03-13 17:21:07 +05:30
Sagar Sharma
9d49afebde Merge branch 'develop' into fix-22-23-05686 2023-03-13 17:05:27 +05:30
Marica
e1d28063b0 Merge branch 'develop' into early-payment-loss 2023-03-13 16:23:24 +05:30
Anand Baburajan
b8703b0b9b Merge branch 'develop' into patch_assdeprsch_gpa_ndb 2023-03-13 15:35:08 +05:30
Ankush Menat
b8a61be080 test: fix hypothesis tests (#34416) 2023-03-13 15:16:30 +05:30
Anand Baburajan
097be8bdea Merge branch 'develop' into patch_assdeprsch_gpa_ndb 2023-03-13 15:08:08 +05:30
Sagar Sharma
f2e9a67f37 Merge branch 'develop' into FIX-ISS-22-23-05720 2023-03-13 14:32:26 +05:30
s-aga-r
442ee3adba fix: operation time for multi-level BOM in WO 2023-03-13 14:31:38 +05:30
Ankush Menat
5bf6fb43a9 chore: fix broken TR translations 2023-03-13 14:12:12 +05:30
Deepesh Garg
7101e7acc4 fix: Filtering issue in payment entry (#34332) 2023-03-13 14:05:13 +05:30
marination
caa1a3dccf fix: Handle rounding more gracefully
- Round off pending discount loss to avoid miniscule losses rounded to 0.0 that are added in deductions
- Use base amounts to calculate base losses instead of using conversion factor which increases rounding error
- Round of total base loss instead of individual income and tax losses to reduce rounding error
- Use default round off account for pending rounding loss in deductions
2023-03-13 14:01:31 +05:30
ruthra kumar
9f26e3c27a Merge pull request #34408 from ruthra-kumar/delete_remarks_migration_patch
chore: delete remarks migration patch
2023-03-13 09:14:21 +05:30
ruthra kumar
da37573b73 chore: delete remarks migration patch
Versions higher than V14.18.2, 'remarks' will be moved in 'migrate_gl_to_payment_ledger'
2023-03-12 13:41:50 +05:30
ruthra kumar
e371bb6672 Merge pull request #34387 from ruthra-kumar/refactor_gl_migration_patch
refactor(patch): remove inner join to improve SQL performance
2023-03-11 21:00:19 +05:30
Mehmet Demirel
fa6d37542b chore: Improve Turkish language translation
chore: Improve Turkish language translation
2023-03-11 19:18:44 +05:30
Deepesh Garg
aae53bb910 fix: Error in consolidated financial statement (#34330) 2023-03-11 19:06:56 +05:30
ruthra kumar
a9989b12d5 Merge pull request #34370 from ruthra-kumar/fix_flaky_test_in_payment_terms_report
fix(test): flaky test case in Payment terms report
2023-03-11 14:17:45 +05:30
ruthra kumar
9d0a1149d8 chore: remove remarks migrations patch from patches.txt
'Remarks' field is moved in migrate_gl_to_payment_ledger patch itself
from versions highers than v14.18.2. Removing it from patches.txt
2023-03-11 13:17:52 +05:30
ruthra kumar
a43304b01b Merge branch 'develop' into fix_flaky_test_in_payment_terms_report 2023-03-11 13:05:38 +05:30
ruthra kumar
7fcd74ed03 fix(test): flaky test case in Payment terms report 2023-03-10 21:23:12 +05:30
ruthra kumar
1744f1d4e4 refactor: add remarks to column as well 2023-03-10 15:57:11 +05:30
Anand Baburajan
6308b509fc Merge branch 'develop' into patch_assdeprsch_gpa_ndb 2023-03-10 15:25:39 +05:30
Deepesh Garg
0157fa15eb chore: Use account closing balance in set gl entries 2023-03-10 13:02:01 +05:30
Sagar Sharma
430378bb6e Merge pull request #34383 from s-aga-r/FIX-ISS-22-23-05836
fix: filters not getting applied on `Web Form`
2023-03-10 00:24:08 +05:30
s-aga-r
9c1e566394 fix: filters not getting applied on Web Form 2023-03-09 22:12:35 +05:30
ruthra kumar
f9cfabf78e refactor(patch): remove inner join to improve SQL performance 2023-03-09 19:42:28 +05:30
Marica
ae0a8a6529 Merge branch 'develop' into early-payment-loss 2023-03-09 18:36:36 +05:30
anandbaburajan
ebb6953274 fix: add missing patch for new fields added in #34214 2023-03-09 17:55:27 +05:30
marination
9abf0ef615 test: Multi currency SI with multi-currency accounting and single currency accounting + Early payment discount 2023-03-09 16:32:36 +05:30
marination
b09c2381ca fix: Multi-currency SI with base currency PE
- Return total discount loss in base currency
- Allocate payment based on terms: Set allocated amount in references table in base currency if accounting is in that currency
- Allocate payment based on terms: While back updating set paid amount (payment schedule) in transaction currency always
- minor: discount msgprint in correct currency
2023-03-09 16:25:45 +05:30
Deepesh Garg
9a8f8e8b7d Revert "fix: Default sales team not getting set" (#34376)
Revert "fix: Default sales team not getting set (#34284)"

This reverts commit 7d0199d743.
2023-03-09 15:36:52 +05:30
Sagar Sharma
428274df56 Merge pull request #34360 from s-aga-r/FIX-ITEM-ALTERNATIVE-ERR-MSG
chore: `Alternative Item Code` error msg
2023-03-09 10:07:35 +05:30
Sagar Sharma
87b5734f5b Merge branch 'develop' into FIX-ITEM-ALTERNATIVE-ERR-MSG 2023-03-09 10:07:24 +05:30
Sagar Sharma
c312692af5 Merge pull request #34362 from s-aga-r/FIX-ISS-22-23-05697
fix: `required_qty` get reset to `1` for Alternative Item in WO
2023-03-09 10:05:08 +05:30
s-aga-r
046834a97a fix: required_qty get reset to 1 for Alternative Item in WO 2023-03-08 20:40:03 +05:30
s-aga-r
baef5ae1ef chore: Alternative Item Code error msg 2023-03-08 20:07:30 +05:30
Deepesh Garg
719ac5c8f3 Merge branch 'develop' of https://github.com/frappe/erpnext into opening_entry 2023-03-08 18:35:26 +05:30
Deepesh Garg
f0267feca8 test: Add test case for closing balance 2023-03-08 18:34:07 +05:30
marination
761f68d7bf fix: Paid amount must be discounted considering accounting currency
- Accounting is in the same currency if party currency and company currency is the same
- If accounting is in the same currency, paid and recvd amount is in the base currency
- Then, discount amount must also be in the base currency as it is deducted from paid amount
- Received amount must be in base currency if not multi currency
- cleanup: Deductions setting broken into smaller functions
2023-03-08 17:20:48 +05:30
Sagar Sharma
a1ad9587fa Merge pull request #34352 from s-aga-r/FIX-ISS-22-23-05722
fix: `BOM Stock Report`
2023-03-08 16:26:19 +05:30
Sagar Sharma
2d66384cbc Merge branch 'develop' into FIX-ISS-22-23-05722 2023-03-08 16:25:42 +05:30
Ankush Menat
52ab11389b chore: drop hypothesis dependency
pinned in framework now
2023-03-08 15:31:25 +05:30
Deepesh Garg
3249a79f07 chore: rename Closing Balance to Account Closing Balance 2023-03-08 15:15:33 +05:30
s-aga-r
b53dcb04ed test: add test cases for BOM Stock Report 2023-03-08 14:00:06 +05:30
s-aga-r
a65b80911b fix: BOM Stock Report 2023-03-08 12:59:50 +05:30
Sagar Sharma
ba1162ff3f Merge pull request #34313 from s-aga-r/fix-22-23-05690
perf: Stock Entry (Material Transfer)
2023-03-07 18:03:08 +05:30
Sagar Sharma
336e0b9666 Merge branch 'develop' into fix-22-23-05690 2023-03-07 18:02:52 +05:30
Solufyin
71de72bdd0 fix: Set contact filter link in Opportunity (#34325)
Co-authored-by: Nihantra C. Patel <n.patel.serpentcs@gmail.com>
2023-03-07 17:44:31 +05:30
Devin Slauenwhite
6de826b8c4 fix: exchange rate revaluation errors (#33947)
* fix: set new balance for non-positive balances

* fix: don't add debit: 0, credit: 0 entries to journal entry.

* fix: add journal entry difference to unbooked gain/loss of exchange.

* chore: linter

* chore: remove invlaid TODO. [skip-ci]
2023-03-07 17:16:15 +05:30
Sagar Sharma
4d1f620d75 Merge branch 'develop' into fix-22-23-05690 2023-03-07 16:35:17 +05:30
Marica
2feb27e399 fix(minor): Dirty the form after clicking on Get advances button in Invoices (#34323)
fix(minor): Dirty form after clicking on Get advances button
2023-03-07 15:45:18 +05:30
Sagar Sharma
4cd16a839b Merge branch 'develop' into fix-22-23-05690 2023-03-07 14:55:46 +05:30
marination
f02fc8acf0 fix: Don't add to deductions if amount is 0
- misc: better docstring
2023-03-07 12:12:45 +05:30
Deepesh Garg
10632d75b0 fix: Do not calculate commission post submit (#34267)
* fix: Do not calculate commision post submit

* chore: Update condition to match server side logic

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>

---------

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2023-03-07 11:44:09 +05:30
Deepesh Garg
7d0199d743 fix: Default sales team not getting set (#34284) 2023-03-07 11:41:26 +05:30
Deepesh Garg
ea8e23384d fix: Payment Request against sales order with disabled rounded total (#34281)
* fix: Payment Request against sales order with disabled rounded total

* chore: Do not consider advance amount
2023-03-07 11:40:29 +05:30
Sagar Sharma
3952b3373d Merge branch 'develop' into fix-22-23-05690 2023-03-07 10:50:39 +05:30
s-aga-r
8ad9e99cea perf: update_completed_qty() in material_request.py 2023-03-07 10:50:11 +05:30
Raffael Meyer
ee12313dbb Merge branch 'develop' into early-payment-loss 2023-03-06 21:41:54 +01:00
s-aga-r
de18f98c5c perf: Stock Entry (Material Transfer) 2023-03-06 23:41:04 +05:30
rohitwaghchaure
53efc8ff77 Merge pull request #34305 from rohitwaghchaure/fixed-not-able-to-complete-bom-update-log
fix: BOM Update log not completed
2023-03-06 23:23:58 +05:30
Sagar Sharma
04b346865f Merge pull request #34301 from barredterra/rename-timezone-utils
refactor: use renamed timezone utils
2023-03-06 22:22:23 +05:30
marination
7f2e7badff fix: Set deduction amount in company currency on Doctype
- Even via JS, deductions amount is always in company currency
- Since there is nothing dynamic about this field, set it in the doctype spec itself
- fixed: Inconsistency between label currency and field currency formatted value
2023-03-06 17:45:26 +05:30
Deepesh Garg
5dabc98ba5 chore: Add index to period closing voucher column 2023-03-06 16:56:33 +05:30
Marica
b5f80815a1 Merge branch 'develop' into early-payment-loss 2023-03-06 15:50:50 +05:30
marination
c217bb2018 test: PE from SI with early payment discount amount & PE assertions in discount % test 2023-03-06 15:02:32 +05:30
marination
2ae5834290 fix: Back update discounted amount in Invoice based on discount type
- Discount value was always trated as a percentage on back updation
2023-03-06 14:54:46 +05:30
Rohit Waghchaure
2f157fa5d3 fix: BOM Update log not completed 2023-03-06 12:09:50 +05:30
Deepesh Garg
310f71c313 test: Add static posting dates to tests 2023-03-05 18:43:26 +05:30
Deepesh Garg
4a2046dfb6 fix: Aggregation with previous closing balance 2023-03-05 18:18:33 +05:30
barredterra
502a37a864 refactor: use renamed timezone utils
https://github.com/frappe/frappe/pull/20253
2023-03-04 19:31:40 +01:00
Sagar Sharma
ac87fca0d7 Merge pull request #34299 from s-aga-r/fix-22-23-05638-2
fix: Stock Reconciliation `actual_qty`
2023-03-04 17:35:05 +05:30
s-aga-r
70de444b7b fix: Stock Reconciliation actual_qty 2023-03-04 17:06:07 +05:30
Sagar Sharma
0185096e09 Merge pull request #34298 from s-aga-r/fix-22-23-05638-1
fix: update inventory dimensions before returning sle
2023-03-04 16:50:55 +05:30
s-aga-r
e6a02719f7 fix: update inventory dimensions before returning sle 2023-03-04 16:02:50 +05:30
Sagar Sharma
31ed4ef6d6 Merge pull request #34293 from s-aga-r/fix-22-23-05638
fix: `Inventory Dimension` for `Stock Reconciliation`
2023-03-04 02:13:13 +05:30
s-aga-r
0e1b7760a8 fix: Inventory Dimension for Stock Reconciliation 2023-03-04 01:05:55 +05:30
s-aga-r
53701c37b1 feat: consider over_order_allowance while validating sales order qty 2023-03-03 22:03:54 +05:30
Devin Slauenwhite
6190b4cf63 chore: revert unrelated changes. 2023-03-03 09:42:29 -05:00
marination
dc2998f544 fix: Set deductions in base currency
- Use field precision to get more accurate values
2023-03-03 17:24:43 +05:30
marination
75ec0a0a85 fix: Recalculate difference amount after setting deductions 2023-03-03 14:13:27 +05:30
Marica
619824855a Merge branch 'develop' into early-payment-loss 2023-03-03 13:53:57 +05:30
marination
768c3a4927 fix: Taxes aren't discounted on early payment discount
- Deductions in payment entry must be split into income loss and tax loss
- Compute total discount in percentage, makes discounting different amounts proportionately easier
2023-03-03 13:21:38 +05:30
s-aga-r
d7da8928ac feat: add field Over Order Allowance (%) in Selling Settings 2023-03-03 11:19:28 +05:30
s-aga-r
8bcbc45add feat: consider over_order_allowance while validating order qty 2023-03-03 11:11:33 +05:30
s-aga-r
fc1088d9c4 fix: don't map item row having 0 qty 2023-03-03 10:50:17 +05:30
s-aga-r
f3993783a3 refactor: rewrite blanket_order.py queries in QB 2023-03-02 17:18:46 +05:30
s-aga-r
f5937f46cb feat: add field Over Order Allowance (%) in Buying Settings 2023-03-02 17:04:09 +05:30
Deepesh Garg
c3d455653e Merge pull request #34258 from deepeshgarg007/finance_book_read_only
chore: Make finance book read only
2023-03-02 16:47:47 +05:30
Deepesh Garg
c089c4156c chore: Minor fixes 2023-03-02 16:46:56 +05:30
s-aga-r
abf9a28d6a fix: hide + button based on Blanket Order Type 2023-03-02 16:40:37 +05:30
Sagar Sharma
6e43d6882a Merge pull request #34117 from s-aga-r/github-issue-33344
refactor: rewrite `get_item_details.py` queries in `QB`
2023-03-02 14:54:58 +05:30
Sagar Sharma
90e1a6bc16 Merge branch 'develop' into github-issue-33344 2023-03-02 14:24:14 +05:30
Sagar Sharma
310643d215 Merge pull request #34273 from s-aga-r/fix-return-pr-serial-no
fix: `rejected_serial_no` not getting copied from PR to PR(Return)
2023-03-02 12:37:39 +05:30
Sagar Sharma
6e9d001819 Merge branch 'develop' into github-issue-33344 2023-03-02 12:09:21 +05:30
Sagar Sharma
50dc0c18eb Merge branch 'develop' into fix-return-pr-serial-no 2023-03-02 12:06:59 +05:30
Ankush Menat
330ae419be fix!: Parse float as per number format in quality inspection (#34259)
fix: Parse float as per number format in quality inspection
2023-03-02 11:59:18 +05:30
s-aga-r
cb0b6de4b9 fix: Serial No is mandatory even if the qty is 0 2023-03-02 11:27:46 +05:30
s-aga-r
a9f0a11ce6 fix: rejected_serial_no not getting copied from PR to PR(Return) 2023-03-02 11:15:46 +05:30
Deepesh Garg
790f0aac12 Merge branch 'develop' into finance_book_read_only 2023-03-02 10:01:12 +05:30
Deepesh Garg
6a89cb98ce Merge pull request #33874 from frappe/alternative-items-quotation
feat: Support for Alternative Items in Quotation
2023-03-01 17:41:24 +05:30
Suraj Shetty
e0a3869874 Merge pull request #34266 from frappe/mergify/bp/develop/pr-34265 2023-03-01 17:06:20 +05:30
Suraj Shetty
6cd2ba5c66 fix: Resolve conflicts
(cherry picked from commit f6469d8398)
2023-03-01 10:59:21 +00:00
Suraj Shetty
46a722d51c fix: Wrap unexpectedly long text in remark
(cherry picked from commit ba66a6714c)

# Conflicts:
#	erpnext/accounts/report/general_ledger/general_ledger.html
(cherry picked from commit b13bf1ebc5)
2023-03-01 10:59:20 +00:00
rohitwaghchaure
32b64db4d6 Merge pull request #34254 from rohitwaghchaure/fixed-subcontracting-stock-availability-issue
fix: consumed qty validation for subcontracting receipt
2023-03-01 15:15:25 +05:30
Deepesh Garg
28dd1a25cb chore: Make finance book read only 2023-03-01 15:00:24 +05:30
Deepesh Garg
e5f603c9d9 perf: Apply closing balance in Trial Balance report 2023-03-01 14:48:06 +05:30
Deepesh Garg
95c9aafda9 fix: Update patch to generate closing balance entries 2023-03-01 14:45:22 +05:30
Deepesh Garg
436fc03eda fix: Closing balance entries for period closing voucher 2023-03-01 14:43:49 +05:30
Rohit Waghchaure
b38fe24090 fix: consumed qty validation for subcontracting receipt 2023-03-01 11:42:59 +05:30
rohitwaghchaure
d88fe27be6 Merge pull request #34195 from HarryPaulo/fix-performance-on-insert-item
fix: Performance improvement when adding a new item
2023-03-01 10:10:14 +05:30
ruthra kumar
f9c75055bb Merge pull request #34241 from ruthra-kumar/bug_on_credit_note_creation
fix: pos return throwing amount greater than grand total
2023-02-28 18:22:30 +05:30
rohitwaghchaure
9bb8e351a2 Merge pull request #34243 from rohitwaghchaure/fixed-date-filters-in-subcontracting-reports
fix: default date in Subcontracting reports
2023-02-28 18:01:14 +05:30
Rohit Waghchaure
dfddc4efc3 fix: default date in Subcontracting reports 2023-02-28 17:53:51 +05:30
rohitwaghchaure
2942cee31e Merge pull request #34235 from rohitwaghchaure/feat-adjust-valuation-rate
feat: adjust purchase receipt valuation rate as per purchase invoice rate
2023-02-28 17:34:53 +05:30
ruthra kumar
35c70f39fa fix: pos return throwing amount greater than grand total 2023-02-28 16:21:32 +05:30
Rohit Waghchaure
a8445da02a fix: labels name 2023-02-28 15:47:45 +05:30
s-aga-r
58c027d4cc chore: Linters 2023-02-28 15:14:34 +05:30
Sagar Sharma
26ced47ddc Merge branch 'develop' into github-issue-33344 2023-02-28 15:01:40 +05:30
Rohit Waghchaure
8e86553717 test: added test cases 2023-02-28 14:57:04 +05:30
Sagar Sharma
90abb28cb4 Merge pull request #34060 from vishdha/pos_fix
fix: multiple Point of Sale conversion issue resolved
2023-02-28 14:55:14 +05:30
Rohit Waghchaure
eab775ef32 feat: adjust purchase receipt valuation rate as per purchase invoice rate 2023-02-28 14:11:55 +05:30
Vishal
f18ae5856f chore: minor changes in pos_controller 2023-02-28 11:03:26 +05:30
Vishal
a51bec0269 chore: minor change 2023-02-28 11:03:26 +05:30
Vishal
3ebe7d861d chore: minor changes added to code 2023-02-28 11:03:26 +05:30
Vishal
1de531e56e fix: multiple pos conversion issue resolved 2023-02-28 11:03:25 +05:30
Sagar Sharma
ecd15d2a65 Merge branch 'develop' into github-issue-33344 2023-02-27 16:57:29 +05:30
Sagar Sharma
9cd42dd60f Merge pull request #34225 from s-aga-r/fix-mr-warehouse
fix: set `from_warehouse` and `to_warehouse` while mapping SE
2023-02-27 12:52:53 +05:30
s-aga-r
c09a61f360 fix: set from_warehouse and to_warehouse while mapping SE 2023-02-27 12:26:21 +05:30
Sagar Sharma
c22641092a Merge pull request #34212 from brian-pond/patch-2
fix: Remove missing DocField in fetch_from
2023-02-27 11:52:53 +05:30
Sagar Sharma
bda1340760 Merge branch 'develop' into patch-2 2023-02-27 11:52:31 +05:30
Patrick Eissler
bbb6a62a7d chore: add german translations (#34167)
* chore: add german translations

* Apply suggestions from code review

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>

---------

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2023-02-27 11:49:22 +05:30
Deepesh Garg
81651beaef Merge pull request #34174 from Vishnu7025/coa-import-currency
fix: currency in coa import
2023-02-27 11:48:44 +05:30
Sagar Sharma
5dcb723fc7 Merge branch 'develop' into patch-2 2023-02-27 11:14:14 +05:30
Brian Pond
83f3e317e1 fix: Remove missing DocField in fetch_from 2023-02-27 11:10:51 +05:30
ruthra kumar
d8b9b83b11 Merge pull request #34207 from ruthra-kumar/fix_permisssion_error_on_work_order_creation
fix: permission error while calling get_work_order_items
2023-02-27 09:55:18 +05:30
Anand Baburajan
9e38b61bd9 Merge pull request #34214 from AnandBaburajan/manual_asset_schedule_develop
fix: asset manual depr schedule [develop]
2023-02-26 20:22:34 +05:30
Anand Baburajan
feeebb1262 Merge branch 'develop' into manual_asset_schedule_develop 2023-02-26 17:40:26 +05:30
anandbaburajan
dd74839eba fix: manual depr schedule 2023-02-26 17:36:36 +05:30
Deepesh Garg
a663df376c fix: Add patch to update closing balances 2023-02-26 16:06:04 +05:30
Deepesh Garg
6607c8bd82 fix: Order by issue in aggregation query 2023-02-26 16:05:26 +05:30
Deepesh Garg
f92c63fb10 feat: Add validations against period closing voucher 2023-02-26 15:53:33 +05:30
Deepesh Garg
7fa7d6b5e4 chore: Rewrite query using query builder 2023-02-26 15:52:30 +05:30
Deepesh Garg
e18336ebe7 feat: Add views in standard filter 2023-02-26 15:47:29 +05:30
rohitwaghchaure
6d6e3cb015 Merge pull request #34206 from rohitwaghchaure/fixed-trivial-error-for-stock-reposting
fix: not able to repost gl entries
2023-02-24 21:10:27 +05:30
ruthra kumar
a11d3327df fix(test): use standalone method to fetch work orders from SO 2023-02-24 21:07:49 +05:30
ruthra kumar
b6bad728cd fix: permission error while calling get_work_order_items 2023-02-24 21:07:46 +05:30
Rohit Waghchaure
7d10dd9ea8 fix: not able to repost gl entries 2023-02-24 17:50:00 +05:30
Deepesh Garg
e26c6dc76b Revert "fix: Concurrency issues in Sales and Purchase returns" (#34202)
Revert "fix: Concurrency issues in Sales and Purchase returns (#34019)"

This reverts commit a67284e96d.
2023-02-24 15:28:14 +05:30
rohitwaghchaure
04f00fd141 Merge pull request #34199 from rohitwaghchaure/fixed-converison-factor-issue
fix: conversion factor not set
2023-02-24 14:56:36 +05:30
Rohit Waghchaure
8e46aebc50 fix: conversion factor not set 2023-02-24 14:49:05 +05:30
HarryPaulo
49af5ba434 fix: Performance improvement when adding a new item 2023-02-23 18:11:09 -03:00
rohitwaghchaure
670304fe8e Merge pull request #34189 from rohitwaghchaure/prevent-to-make-item-price-for-template
fix: user shouldn't able to make item price for item template
2023-02-23 20:47:48 +05:30
Rohit Waghchaure
6417ae0ee8 fix: user shouldn't able to make item price for item template 2023-02-23 20:21:50 +05:30
Deepesh Garg
c3f39c3f32 feat: Cascade closing balances on PCV submit 2023-02-23 16:48:54 +05:30
Deepesh Garg
36c08d0835 fix: Add patches to create accounting dimension in Closing Balance 2023-02-23 16:46:37 +05:30
Marica
47ab26dedf Merge branch 'develop' into alternative-items-quotation 2023-02-23 13:20:28 +05:30
ruthra kumar
a9920715ab Merge pull request #34022 from ruthra-kumar/gross_profit_memory_and_performance_issue
perf: Gross Profit report will fetch SLE's on demand and memoize
2023-02-23 11:55:08 +05:30
ruthra kumar
88d888d9d0 refactor: use docstatus from Delivery Note Item 2023-02-23 11:15:56 +05:30
rohitwaghchaure
3692f960d0 Merge pull request #34172 from rohitwaghchaure/zero-rate-adjust-issue-using-lcv
fix: zero division error while making LCV
2023-02-23 10:54:01 +05:30
ruthra kumar
60d3b86cdb Merge pull request #34176 from ruthra-kumar/fix_ui_freeze_on_sales_invoice
fix: ui freeze on item selection in sales invoice
2023-02-23 10:35:50 +05:30
rohitwaghchaure
e3de216e06 Merge pull request #34173 from rohitwaghchaure/incorrect-color-showing-in-report
fix: incorrect color in the BOM Stock Report
2023-02-23 09:54:45 +05:30
ruthra kumar
6412583e98 fix: ui freeze on item selection in sales invoice 2023-02-23 09:36:21 +05:30
vishnu
e3c000d0be chore: change column label 2023-02-22 10:53:11 +00:00
vishnu
19c0b7a523 fix: currency in coa import 2023-02-22 10:24:45 +00:00
Rohit Waghchaure
a8f03ebf7f fix: incorrect color in the BOM Stock Report 2023-02-22 14:24:18 +05:30
Rohit Waghchaure
80e94a08cf fix: zero division error while making LCV 2023-02-22 13:29:06 +05:30
Deepesh Garg
b44a19bd1a feat: Introduce opening entry for reporting 2023-02-21 23:20:28 +05:30
Sankara Subramanian V
a06d24037b refactor(region): Splitting of KSA(Saudi Arabia) Regional logic from ERPNext (#33895)
* feat: remove KSA regional code
2023-02-21 22:52:20 +05:30
ruthra kumar
dde5bbc9a7 Merge pull request #34102 from ruthra-kumar/pos_validate_for_duplicate_pos_invoices
fix: check for duplicate pos invoices in closing entry
2023-02-21 18:45:39 +05:30
ruthra kumar
47add0b751 fix: check for duplicate in pos closing and pos merge log entry 2023-02-21 17:50:57 +05:30
Deepesh Garg
9739d8b52a feat: Introduce opening entry for reporting 2023-02-21 15:23:29 +05:30
ruthra kumar
4a7b1de2d8 refactor: clear records in batches in 'Transaction Deletion Record' (#34109)
refactor: clear records in batches
2023-02-21 14:27:00 +05:30
Deepesh Garg
c88444a6c4 fix: Filters in item-wise sales history report (#34145) 2023-02-21 14:26:33 +05:30
Anand Baburajan
5e3a034395 Merge pull request #34153 from AnandBaburajan/fixed_asset_report_fiscal_year
fix: fiscal year error for existing assets in fixed asset register
2023-02-21 13:54:54 +05:30
Anand Baburajan
b781c57dcb Merge branch 'develop' into fixed_asset_report_fiscal_year 2023-02-21 13:10:07 +05:30
Himanshu Shivhare
3547252217 Telegram Group link updated (#34149) 2023-02-21 13:05:03 +05:30
anandbaburajan
76861eb332 fix: fiscal year error for existing assets in fixed asset register 2023-02-21 13:04:01 +05:30
Deepesh Garg
35cdd996a9 fix: Use normal rounding for Tax Withholding Category (#34114) 2023-02-21 12:57:49 +05:30
Sagar Sharma
18541ef54f Merge pull request #34138 from s-aga-r/dn-create-button
fix(ux): `ReferenceError: me is not defined` Delivery Note
2023-02-21 10:26:52 +05:30
Sagar Sharma
77b88961f6 Merge branch 'develop' into dn-create-button 2023-02-21 10:19:09 +05:30
marination
6b789e2f04 fix: Map only non alternative items from Quotation in Sales Invoice
- Since there's no item selection, only Quotation selection :/
2023-02-20 21:17:43 +05:30
marination
19456127cf fix: Handle Get Items From in Sales Order
- Map all non alternatives from Quotation to SO if no selected items
- Show disclaimer mentioning that Qtns with alternatives must be mapped to SO from the Qtn form
2023-02-20 20:52:14 +05:30
Ankush Menat
3f2a2c96f6 fix: Add company perm check unconditionally (#34142)
fix: Add employee perm check unconditionally
2023-02-20 16:07:27 +05:30
rohitwaghchaure
5e9620b98b Merge pull request #34139 from rohitwaghchaure/fixed-stock-ledger-report-filter-issue
fix: inventory dimension filter not overriding with existing filter for stock ledger report
2023-02-20 13:04:23 +05:30
rohitwaghchaure
3871cf7110 Merge pull request #33722 from rohitwaghchaure/purchase-invoice-performance-issue
fix: purchase invoice performance issue
2023-02-20 12:47:07 +05:30
Rohit Waghchaure
0e388ba872 fix: inventory dimension filter not overriding with existing filter for stock ledger report 2023-02-20 12:28:43 +05:30
Marica
3c96791d52 fix: Use block variable
Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-02-20 12:04:14 +05:30
s-aga-r
44ee9f0f19 chore: Linters 2023-02-20 11:43:32 +05:30
s-aga-r
1b010add26 fix(ux): ReferenceError: me is not defined Delivery Note 2023-02-20 11:17:49 +05:30
Sagar Sharma
5bbe8728ad Merge branch 'develop' into github-issue-33344 2023-02-20 10:47:29 +05:30
Ankush Menat
e84e778151 chore(deps): remove stdnum dependency (#34137) 2023-02-20 10:40:07 +05:30
Sagar Sharma
c8fda8a8b5 Merge branch 'develop' into github-issue-33344 2023-02-19 22:17:20 +05:30
Alirio Castro
183e42af1a fix: differency entry journal debit/credit missing (#34104)
* fix: difference entry journal is wrong

* fix: difference entry journal is wrong
2023-02-19 19:40:13 +05:30
Johannes Obermeier
2a90fad710 feat(stock): Support more barcodes in an item by validate the barcode with the barcodenumber module (#33863)
feat(stock): Support more barcodes in an article by validate the barcode with the barcodenumber module
2023-02-19 19:36:05 +05:30
Sagar Sharma
2959285c82 Merge branch 'develop' into fix-reserve-qty 2023-02-19 12:45:39 +05:30
Sagar Sharma
f342e6e765 Merge branch 'develop' into github-issue-33344 2023-02-19 12:17:33 +05:30
ruthra kumar
c722f2819c fix: ignore repost payment ledger on basic documents cancellation (#34054)
fix: ignore repost payment ledger on cancel/delete of Inv/Pay/JE's

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-02-19 12:09:10 +05:30
Sagar Sharma
2c3973156f Merge branch 'develop' into github-issue-33344 2023-02-19 12:07:27 +05:30
Richard Case
5b7d23de15 feat: bank reconciliation and plaid changes (#33986)
fix: plaid link refresh: update account ids
fix: plaid transactions for credit cards & add accounts on link refresh if they don't exist
fix: bank reconciliation amount matching
fix: bank reconciliation dialog usability
feat: rewrite bank transaction reconciliation to allow multiple transactions to reconcile against vouchers before clearance
fix: matching transaction amounts and race condition bug
fix: ensure there is a reference number in plaid transactions and other tweaks
feat: add references to Payroll Entry Bank Journal Entry
feat: only clear Voucher once all Bank GLEs are allocated to Bank Transactions
fix: strange type error
feat: add payment method field to bank and plaid transactions and prepopulate relevant bank reconciliation new voucher fields
feat: bank reconciliation - allow bank transactions to reconcile against themselves for when there are banking amendments
fix: bank transaction self-reconcile bug and tidy
fix: bank reconciliation datatable index update
2023-02-19 11:50:17 +05:30
Shadrak Gurupnor
5e48e61c66 fix: forced delete linked desktop_icons (#34107)
* fix: forced delete linked desktop_icons

* fix: black
2023-02-19 11:42:35 +05:30
ruthra kumar
9c6466f15b fix: consider rounded total amount while making payment request (#34110) 2023-02-19 11:41:41 +05:30
Devin Slauenwhite
c76352340d fix(ux): customer/supplier docfield layout (#34125) 2023-02-19 11:37:32 +05:30
Sagar Sharma
07c6ad6fa7 Merge branch 'develop' into github-issue-33344 2023-02-18 22:24:06 +05:30
s-aga-r
35489fbbf9 refactor: remove method get_serial_no_batchwise from get_item_details.py 2023-02-18 22:23:53 +05:30
s-aga-r
6b144baa69 refactor: rewrite get_item_details.py queries in QB 2023-02-18 22:23:51 +05:30
rohitwaghchaure
dff9655d46 Merge pull request #34115 from rohitwaghchaure/fixed-convert-to-item-warehouse-reposting
feat: provision to convert transaction based reposting to item wareho…
2023-02-18 21:31:20 +05:30
Rohit Waghchaure
f1383b5ef9 feat: provision to convert transaction based reposting to item warehouse based reposting 2023-02-18 19:31:48 +05:30
Sagar Sharma
c292859b59 Merge pull request #34077 from s-aga-r/purchase-order-portal
fix: show Purchase Order Portal `Pay` button based on configuration
2023-02-18 12:20:14 +05:30
Sagar Sharma
91983fb4c6 Merge branch 'develop' into purchase-order-portal 2023-02-17 23:17:00 +05:30
Prateek
b93c18bd4a fix: use max function to get default company address 2023-02-17 20:25:13 +05:30
rohitwaghchaure
47264481ad Merge branch 'develop' into purchase-invoice-performance-issue 2023-02-17 16:41:30 +05:30
Anand Baburajan
6b3028d77b Merge pull request #34111 from AnandBaburajan/asset_fixes_17_feb
fix: repair status after deletion, asset status after manual depr entry and other misc bugs [develop]
2023-02-17 16:12:45 +05:30
anandbaburajan
e50bd52162 fix: asset repair status after deletion and asset status after manual depr entry 2023-02-17 15:32:24 +05:30
Sagar Sharma
ee21850ab8 Merge branch 'develop' into purchase-order-portal 2023-02-17 11:08:30 +05:30
ruthra kumar
067f8c1d70 Merge pull request #34071 from ruthra-kumar/rearrange_patch_order
patch: reorder migration patches
2023-02-17 11:04:36 +05:30
ruthra kumar
68202639f5 chore: reorder migration patches.
'migrate_gl_to_payment_ledger',
'migrate_remarks_from_gl_to_payment_ledger' should always run last.
2023-02-17 10:03:55 +05:30
rohitwaghchaure
4399a93843 Merge pull request #34091 from rohitwaghchaure/fixed-incorrect-consumed-qty-in-scr
fix: incorrect consumed qty in subcontracting receipt
2023-02-16 15:10:14 +05:30
Sagar Sharma
758f47bba6 Merge branch 'develop' into purchase-order-portal 2023-02-16 14:28:05 +05:30
Sagar Sharma
70660191a6 Merge pull request #34090 from frappe/update-codeowners
chore: update `CODEOWNERS`
2023-02-16 14:26:11 +05:30
Sagar Sharma
320f3c1ac0 Merge branch 'develop' into update-codeowners 2023-02-16 14:25:19 +05:30
Rohit Waghchaure
156e45970a fix: incorrect consumed qty in subcontracting receipt 2023-02-16 14:17:27 +05:30
HENRY Florian
4d79ffe3c6 fix: rename duplicate field name with same type into a DocType to avoid import Error (#34053)
* fix: Delivery Note field label set

* fix: Item field label de-duplicate name

* fix: Payment Entry field label de-duplicate name

* fix: Pruicing Rule field label de-duplicate name

* fix: Project field label de-duplicate name

* fix: Timesheet field label de-duplicate name

* Update erpnext/accounts/doctype/pricing_rule/pricing_rule.json

Co-authored-by: Sagar Sharma <sagarsharma.s312@gmail.com>

* Update erpnext/stock/doctype/item/item.json

Co-authored-by: Sagar Sharma <sagarsharma.s312@gmail.com>

---------

Co-authored-by: Sagar Sharma <sagarsharma.s312@gmail.com>
2023-02-16 13:46:19 +05:30
Sagar Sharma
e8b8c51d82 chore: update CODEOWNERS 2023-02-16 12:55:37 +05:30
Sagar Sharma
fb5796f18f Merge branch 'develop' into purchase-order-portal 2023-02-16 11:22:19 +05:30
Tej Pochiraju
3f44ef8790 Allow bulk import of party specific item (#34083)
Co-authored-by: Tej Pochiraju <tej@iotready.co>
2023-02-16 10:11:25 +05:30
Sagar Sharma
471e77b931 Merge branch 'develop' into purchase-order-portal 2023-02-15 22:46:07 +05:30
Sagar Sharma
c793fb0bb4 Merge pull request #34086 from s-aga-r/github-issue-33930
fix: create `Delivery Trip` from `Delivery Note` list
2023-02-15 22:40:10 +05:30
Sagar Sharma
c7a540b7e2 Merge branch 'develop' into github-issue-33930 2023-02-15 22:37:52 +05:30
s-aga-r
6c6195bae6 fix: create Delivery Trip from Delivery Note list 2023-02-15 22:37:26 +05:30
Sagar Sharma
421e34a181 Merge branch 'develop' into purchase-order-portal 2023-02-15 21:49:09 +05:30
Sagar Sharma
0cd69c8700 Merge pull request #34080 from s-aga-r/batch-no-item
chore: copy `item_code` to `Batch` while creating new batch from SCR
2023-02-15 21:39:07 +05:30
Sagar Sharma
46afbb594a Merge branch 'develop' into fix-reserve-qty 2023-02-15 21:37:30 +05:30
s-aga-r
ffa9c6e4d9 chore: copy item_code to Batch while creating new batch from SCR 2023-02-15 20:16:42 +05:30
s-aga-r
20bdc63b03 fix: show Purchase Order Portal Pay button based on configuration 2023-02-15 20:14:39 +05:30
marination
74fab53e28 test: Alternative items in Quotation
- Taxes and totals, mapping, back updation
2023-02-15 15:04:00 +05:30
s-aga-r
d7ef5ad955 chore: add field show_pay_button in Buying Settings 2023-02-15 14:43:10 +05:30
Marica
22010b745c Merge branch 'develop' into alternative-items-quotation 2023-02-15 13:05:33 +05:30
Anand Baburajan
d3ff289779 Merge pull request #34057 from AnandBaburajan/more_asset_bug_fixes
fix: manual depr entries in asset_depreciations_and_balances report and some misc bugs [develop]
2023-02-15 12:32:35 +05:30
Anand Baburajan
ef56060166 Merge branch 'develop' into more_asset_bug_fixes 2023-02-15 11:55:55 +05:30
rohitwaghchaure
2e43123048 Merge pull request #34065 from barredterra/print-rfq-letterhead
fix: change parameter name for letter head
2023-02-15 09:31:06 +05:30
rohitwaghchaure
9235918d65 Merge pull request #34061 from rohitwaghchaure/feat-allow-to-make-in-transit-entry
feat: allow to make in transit transfer entry from material request
2023-02-15 09:08:22 +05:30
barredterra
d5b7f2e49e test: download RFQ PDF 2023-02-14 19:53:39 +01:00
barredterra
8e40c04494 refactor: download RFQ PDF 2023-02-14 19:53:03 +01:00
barredterra
f7fd30fecf fix: change parameter name for letter head
To match changes from https://github.com/frappe/frappe/pull/19627
2023-02-14 19:34:36 +01:00
Devin Slauenwhite
4c5147f270 Merge: upstream/develop into pps190/fix-reserve-qty 2023-02-14 10:22:54 -05:00
Deepesh Garg
e69ea17f59 Merge pull request #34059 from AnandBaburajan/anand_codeowners
chore: add anand to asset's codeowner
2023-02-14 19:38:46 +05:30
Rohit Waghchaure
5b6128848f feat: allow to make in transit transfer entry from material request 2023-02-14 19:03:07 +05:30
Anand Baburajan
662ebc5c1a Merge branch 'develop' into anand_codeowners 2023-02-14 18:35:05 +05:30
anandbaburajan
d003370f61 chore: add anand to asset's codeowner 2023-02-14 18:33:01 +05:30
Anand Baburajan
b0cfb0b9ef Merge branch 'develop' into more_asset_bug_fixes 2023-02-14 18:09:55 +05:30
anandbaburajan
a58f2e6c03 fix: asset_depreciation_and_balances report doesn't reflect manual depr entries 2023-02-14 17:59:16 +05:30
Sagar Sharma
75d9dbca43 Merge pull request #34018 from s-aga-r/fix-so-on-hold
fix: update `reserved_qty` when `Sales Order` marked as `Hold`
2023-02-14 16:51:56 +05:30
Sagar Sharma
447310702e Merge branch 'develop' into fix-so-on-hold 2023-02-14 16:01:43 +05:30
ruthra kumar
960085853a Merge pull request #34048 from ruthra-kumar/typeerror_on_sales_order_analysis
fix: typeerror on Sales Order analysis report
2023-02-14 15:27:36 +05:30
Sagar Sharma
5faa62c49a Merge branch 'develop' into fix-so-on-hold 2023-02-14 11:06:10 +05:30
rohitwaghchaure
3014bac293 Merge pull request #34046 from FHenry/dev_fix_BOM_import
fix: BOM import failed as use same label field for Raw Materials Item table and Scrap Item table
2023-02-14 10:29:26 +05:30
ruthra kumar
00a4191966 fix: typeerror on Sales Order analysis report 2023-02-14 09:56:35 +05:30
Raffael Meyer
770369e5c1 feat: translate fixtures during runtime, not installation (#33996)
feat: install untranslated fixtures from files

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-02-14 09:29:27 +05:30
Florian HENRY
86be259341 fix: BOM import failed as importer use same label field for Raw MaterialsItem table and Scrap Item table 2023-02-13 23:34:20 +01:00
Deepesh Garg
ce748cec3a fix: Amount validation in Payment Request against Purchase Order (#34042) 2023-02-13 20:56:24 +05:30
HENRY Florian
231fe4156f fix: should never get cutomer price on purchase document (#34002)
* fix: never get cutomer price on purchase document

chores: syntax

chore: typo in stock_entry get_uom_details (#33998)

fix: typo in stock_entry get_uom_details

chores: syntax

* feat: add test for get_item_detail price list oriented

* feat: add test for get_item_detail price price oriented

* feat: add test for get_item_detail price price oriented

* chore: clean test code
2023-02-13 20:56:05 +05:30
anandbaburajan
c533213225 fix: opening_accumulated_depreciation and precision in charts 2023-02-13 17:22:31 +05:30
Deepesh Garg
ff4ae69408 Merge branch 'develop' into gross_profit_memory_and_performance_issue 2023-02-13 15:38:26 +05:30
Deepesh Garg
a67284e96d fix: Concurrency issues in Sales and Purchase returns (#34019) 2023-02-13 15:31:19 +05:30
ruthra kumar
4f2553e7b6 Merge pull request #34021 from ruthra-kumar/handle_rare_cases_of_null_in_outstanding_calculation
fix: rare instances of IntegrityError while cancelling journals against cr note
2023-02-13 14:14:27 +05:30
ruthra kumar
192a3395a5 refactor: filter only immediate upcoming payment term for each SO (#33923)
* fix: ignore closed or 'on hold' orders

* refactor: filter immediate upcoming term

---------

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-02-13 12:36:40 +05:30
ruthra kumar
e5a2b15fba fix: unwanted difference amount calculation on cr note and invoice with same currency (#34020)
* fix: incorrect difference amount while reconiling cr/dr notes

* fix(test): catch incorrect difference amount calculation

Fixed issues where difference amount was calculated for Cr Notes and Invoices of
the same currency.

---------

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-02-13 12:08:42 +05:30
Deepesh Garg
148703bfc2 feat: Setting to allow Sales Order creation against expired quotation (#33952)
* feat: Setting to allow Sales Order creation against expired quotation

* chore: linting issues
2023-02-13 10:27:55 +05:30
Deepesh Garg
ce3f9622cb Merge branch 'develop' into handle_rare_cases_of_null_in_outstanding_calculation 2023-02-13 09:42:41 +05:30
Deepesh Garg
48bb2c942b fix: Ignore Payment Ledger Entry on dunning cancel (#34025)
* fix: Ignore Payment Ledger Entry on dunning cancel

* chore: fix translation issue
2023-02-13 09:42:01 +05:30
Deepesh Garg
77f6789706 Revert "Update tr.csv" (#34026)
Revert "chore: Update Turkish translations (#33985)"

This reverts commit 6ea0a69d3a.
2023-02-13 08:27:00 +05:30
ruthra kumar
3e5691072a perf: fetch SLE's on demand and memoize 2023-02-12 14:49:17 +05:30
ruthra kumar
b9a7ff7c3d fix: IntegrityError while cancelling journals against cr note 2023-02-12 14:06:40 +05:30
Sagar Sharma
b0e8dfc1d0 Merge branch 'develop' into fix-so-on-hold 2023-02-12 13:37:21 +05:30
s-aga-r
d76759e066 fix: update reserved_qty when Sales Order marked as Hold 2023-02-12 13:36:26 +05:30
Richard Case
a0eb5e5535 fix: add payment hook to point of sale JS (#33988) 2023-02-11 20:40:15 +05:30
Raffael Meyer
e4953df4a3 fix: set per_billed based on hours when amounts are zero (#33984)
* fix: set per_billed based on hours when amounts are zero

* test: calculate_percentage_billed
2023-02-11 12:36:37 +05:30
Sabu Siyad
0df28c7174 fix(ecommerce): throw invalid doctype error in shop by category (#33901)
Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-02-11 12:28:42 +05:30
Raffael Meyer
201573ab9a refactor: install fixtures (#33964)
* refactor: install fixtures

* style: disable semgrep for install_defaults signature
2023-02-11 12:15:42 +05:30
Deepesh Garg
0efdc6c13a fix: Ignore mandatory fields while creating tax templates for new companies (#34005) 2023-02-11 12:03:48 +05:30
Raffael Meyer
ab7293bcd3 fix: list view for Terms and Conditions (#33925)
Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-02-11 11:09:26 +05:30
Mehmet Demirel
6ea0a69d3a chore: Update Turkish translations (#33985)
We are the ERPNext Turkey Team.
We request confirmation of the translation we sent.
2023-02-11 09:27:18 +05:30
Deepesh Garg
e478a5d0ce feat: Add filters in Loan Interest Report (#33907) 2023-02-11 09:17:24 +05:30
Deepesh Garg
47c91324b1 fix: Amount for debit and credit notes with 0 qty line items (#33902) 2023-02-11 09:04:00 +05:30
Akshay
185c543b73 chore: typo in stock_entry get_uom_details (#33998)
fix: typo in stock_entry get_uom_details
2023-02-10 20:42:35 +05:30
Devin Slauenwhite
5685492995 Merge remote-tracking branch 'frappe/develop' into fix-reserve-qty
# Conflicts:
#	erpnext/stock/doctype/delivery_note/test_delivery_note.py
2023-02-09 13:48:18 -05:00
Marica
bd7e6e264e Merge branch 'develop' into alternative-items-quotation 2023-02-06 16:30:10 +05:30
marination
db2076db69 refactor: Order based alternative items mapping
- Alternatives must be followed by a non-alternative item row
- On submit, store non-alternative rows in hidden checkbox to avoid recomputation
- Check for valid/mappable rows by row name
- UI: Select from table rows.Add single row for original/alternative item in dialog
- UI: Indicator for alternative items in dialog grid
- UI: Indicator legend and description of table
- DB: Added check field 'Has Alternative Item' not to be confused with 'Has Alternative' in Mfg
2023-02-06 16:25:38 +05:30
Anand Baburajan
9d8502f406 Merge pull request #33946 from AnandBaburajan/cancel_pi_cancelled_asset
fix: allow cancelling purchase invoice if linked asset is already cancelled
2023-02-05 16:06:47 +05:30
Anand Baburajan
4686217d3c Merge branch 'develop' into cancel_pi_cancelled_asset 2023-02-05 14:14:39 +05:30
Anand Baburajan
52435a3a7f Merge pull request #33945 from AnandBaburajan/manual_depr_entries_develop
fix: manual depr entry not updating asset value [develop]
2023-02-05 14:14:19 +05:30
Anand Baburajan
396f455258 Merge branch 'develop' into cancel_pi_cancelled_asset 2023-02-05 12:19:21 +05:30
Anand Baburajan
f8270f093d Merge branch 'develop' into manual_depr_entries_develop 2023-02-05 12:19:17 +05:30
Sagar Sharma
05f4b659a7 Merge pull request #33942 from s-aga-r/github-issue-33533
fix: stock entry from item dashboard (stock levels)
2023-02-05 09:46:27 +05:30
Sagar Sharma
2fedd595a9 Merge branch 'develop' into github-issue-33533 2023-02-05 09:36:17 +05:30
rohitwaghchaure
0352e1dace Merge pull request #33936 from rohitwaghchaure/fixed-negative-stock-error
fix: negative stock error
2023-02-04 23:34:56 +05:30
rohitwaghchaure
7d794bc70a Merge branch 'develop' into fixed-negative-stock-error 2023-02-04 22:35:58 +05:30
rohitwaghchaure
67b5471d09 Merge pull request #33941 from developsessions/fix_wrong_due_date_calculation
fix: default due_date was wrong calculated on template "_Test Payment Term Template 1" (last day of next month)
2023-02-04 22:34:47 +05:30
Anand Baburajan
82490d9f55 Merge branch 'develop' into cancel_pi_cancelled_asset 2023-02-04 18:37:34 +05:30
Anand Baburajan
07a0e2b7a8 Merge branch 'develop' into manual_depr_entries_develop 2023-02-04 18:37:34 +05:30
developsessions
c8cd351b39 style: apply results of lint run 2023-02-04 09:12:29 +01:00
Sagar Sharma
4a6a7593c3 Merge pull request #33940 from s-aga-r/github-issue-33917
chore: report `Warehouse wise Item Balance Age and Value`
2023-02-04 13:27:57 +05:30
anandbaburajan
3380dc5dea chore: use continue, not break 2023-02-04 11:20:26 +05:30
developsessions
9d0096ad9e fix: failed test, convert date time to string 2023-02-03 21:21:43 +01:00
Anand Baburajan
bb424965ee Merge branch 'develop' into cancel_pi_cancelled_asset 2023-02-03 23:00:40 +05:30
anandbaburajan
b961321de5 fix: allow PI cancel if linked asset is cancelled 2023-02-03 22:58:22 +05:30
Anand Baburajan
2d54bf7199 Merge branch 'develop' into manual_depr_entries_develop 2023-02-03 22:25:27 +05:30
anandbaburajan
e5da0d7a63 chore: refactor AssetDepreciationSchedule 2023-02-03 22:23:17 +05:30
anandbaburajan
8ea9e4576f fix: asset value for manual depr entries 2023-02-03 21:43:18 +05:30
developsessions
be1f941996 fix: Add missing 1 required positional argument: 'bill_date' 2023-02-03 14:50:44 +01:00
developsessions
c80aaad437 style: lint wrong from position 2023-02-03 13:55:36 +01:00
s-aga-r
dc0ddf8d7e fix: stock entry from item dashboard (stock levels) 2023-02-03 18:08:34 +05:30
developsessions
ce8a1086a7 fix: default due_date was wrong calculated on template "_Test Payment Term Template 1" (last day of next month) 2023-02-03 11:30:29 +01:00
s-aga-r
56356ffbb9 chore: add Item Name column in Warehouse wise Item Balance Age and Value report 2023-02-03 12:28:23 +05:30
s-aga-r
d7a665cb84 chore: column width in Warehouse wise Item Balance Age and Value report 2023-02-03 12:27:41 +05:30
Rohit Waghchaure
9ae7578b07 test: test case 2023-02-02 18:54:42 +05:30
Rohit Waghchaure
6d513e2519 fix: negative stock error 2023-02-02 18:40:15 +05:30
marination
03321f5f13 chore: Code simplification
- Map is not required, avoid filter multiple times, use single loop instead
- Better variable name
- Reduce LOC
2023-02-02 17:28:03 +05:30
ruthra kumar
2afed7de03 Merge pull request #33777 from ruthra-kumar/performance_tuning_remarks_migration
fix(patch): reduce memory usage while migrating remarks
2023-02-02 16:47:15 +05:30
ruthra kumar
ae2de3cf65 Merge pull request #33776 from ruthra-kumar/performance_tuning_ple_migration
patch: reduce memory usage by paging through records
2023-02-02 16:46:51 +05:30
ruthra kumar
cb1d33880c Merge pull request #33502 from ruthra-kumar/toggle_account_balances_in_coa
feat: Toggle display of Account Balance in Chart of Accounts
2023-02-02 09:20:53 +05:30
marination
b3fe7c6dad fix: Consider only ordered alternative/original item for Quotation status
- The original and its alternatives make a set of items where one is chosen
- While setting order status of Quotation, check if the chosen item from the set is fully ordered or not
- Filter out unselected items from the set
- Create a map containing the set of items and if they were ordered or not for ease of grouping
- The simple items will work as it used to
2023-02-01 19:10:32 +05:30
Gokulnath
2884738864 feat: adding warehouse filter for gross profit report (#33397)
Co-authored-by: ruthra kumar <ruthra@erpnext.com>
2023-02-01 18:44:15 +05:30
rohitwaghchaure
fbf2d7e9de Merge pull request #33918 from rohitwaghchaure/fixed-incorrect-bin-qty
fix: incorrect actual qty in Bin
2023-02-01 18:22:56 +05:30
Rohit Waghchaure
f8c852c54c fix: incorrect actual qty in Bin 2023-02-01 17:49:11 +05:30
Suraj Shetty
ffeda0cee9 Merge pull request #33916 from gavindsouza/permlevel-apis 2023-02-01 16:24:18 +05:30
Dany Robert
2cc7239dd5 fix: currency formatting in item-wise sales history (#33903)
* fix(item-sales-history): currency formatting

* chore: linting issues

* fix: convert raw sql to qb
2023-02-01 14:27:38 +05:30
Gavin D'souza
940ad6e3f2 fix: Fetch all fields via get_returned_qty_map_for_row 2023-02-01 13:53:37 +05:30
Gavin D'souza
3518d4be1d fix(update_billing_percentage): Remove permlevel checks on aggregated
value
2023-02-01 12:58:08 +05:30
Raffael Meyer
3c7b460fd8 fix: german chart of accounts "SKR03" (#33909)
* fix: german chart of accounts "SKR03"

- Added some missing account types and tax rates
- Added some missing accounts

* style: convert indentation to tabs

* fix: space before percentage sign

* feat: add some expense accounts

* refactor: replace unicode characters with utf-8

for better readability

* revert: add back groups for Bank and Cash accounts

Removed in 7d0d9c6900
2023-02-01 12:16:58 +05:30
Deepesh Garg
103a91ed40 Merge pull request #33808 from dj12djdjs/fix-lead-rename
fix: make title field readonly
2023-02-01 12:02:33 +05:30
ruthra kumar
9bb64107c5 perf: reduce memory usage while migrating remarks
Page through records using primary key
2023-02-01 10:44:44 +05:30
Sagar Sharma
4ac983cf09 Merge pull request #33910 from barredterra/named-place-rfq
feat: add incoterm named place to RFQ
2023-02-01 10:40:09 +05:30
barredterra
7156184933 feat: add incoterm named place to RFQ 2023-01-31 23:23:54 +01:00
marination
ece6358e60 fix: Iterate over list instead of map's output and formatting 2023-01-31 17:13:05 +05:30
rohitwaghchaure
c5834c1db4 Merge pull request #33896 from rohitwaghchaure/inventory-dimension-mandatory
feat: mandatory and mandatory depends on in inventory dimension
2023-01-31 15:18:14 +05:30
rohitwaghchaure
ddb4396117 Merge pull request #33715 from s-aga-r/fix-pick-list
fix: consider existing pick-list
2023-01-31 15:10:19 +05:30
Sagar Sharma
510b265830 Merge pull request #33869 from s-aga-r/fix-mr-rate-and-amount
fix: `amount` in `Material Request`
2023-01-31 14:44:11 +05:30
s-aga-r
6ffdeb1af8 fix: consider stock_qty if picked_qty is zero 2023-01-31 14:39:57 +05:30
Rohit Waghchaure
22d0e1373b test: added test case 2023-01-31 14:36:26 +05:30
Rohit Waghchaure
423f2b5627 feat: mandatory and mandatory depends on in inventory dimension 2023-01-31 14:19:14 +05:30
Sagar Sharma
6e015fd6be Merge branch 'develop' into fix-mr-rate-and-amount 2023-01-31 12:39:38 +05:30
Sagar Sharma
57c8871de0 Merge branch 'develop' into fix-pick-list 2023-01-31 12:38:58 +05:30
s-aga-r
0b76a26c8a refactor: test_consider_existing_pick_list() 2023-01-31 12:38:30 +05:30
s-aga-r
bb7fe795fe test: add test cases 2023-01-31 12:38:30 +05:30
s-aga-r
207eeefc85 fix(test): test_pick_list_for_items_with_multiple_UOM() 2023-01-31 12:38:30 +05:30
s-aga-r
5138ef0160 fix: pymysql.err.ProgrammingError 2023-01-31 12:38:30 +05:30
s-aga-r
7b3d496ce0 fix: get_picked_items_details 2023-01-31 12:38:30 +05:30
s-aga-r
be41052dc8 chore: add status field in Pick List 2023-01-31 12:38:30 +05:30
s-aga-r
b642718f08 fix: consider existing pick list 2023-01-31 12:38:27 +05:30
Deepesh Garg
b3dc22de29 fix: Fetch commission rate from sales partner (#33851) 2023-01-31 09:33:33 +05:30
Anand Baburajan
e007776ada Merge pull request #33888 from barredterra/get-asset-value
fix(Fixed Asset Register): error when selecting more than one fiscal …
2023-01-31 01:59:53 +05:30
barredterra
11d165c274 fix(Fixed Asset Register): error when selecting more than one fiscal year 2023-01-30 19:33:58 +01:00
Anand Baburajan
3e5f8323b0 Merge pull request #33883 from AnandBaburajan/fix_disposal_was_made_on_original_schedule_date_develop
fix: disposal_was_made_on_original_schedule_date [develop]
2023-01-30 22:02:34 +05:30
Anand Baburajan
5d8a2d3d3b Merge branch 'develop' into fix_disposal_was_made_on_original_schedule_date_develop 2023-01-30 21:36:51 +05:30
anandbaburajan
f487660a7c fix: disposal_was_made_on_original_schedule_date 2023-01-30 21:33:43 +05:30
Deepesh Garg
2bad86d8d8 ci: bump isort to 5.12.0 (#33875)
[skip ci]
2023-01-30 19:58:23 +05:30
ruthra kumar
5f38859a04 Merge pull request #33736 from rtdany10/gp-report-fix
fix(gp): fetch buying amount from dn related to so
2023-01-30 19:04:36 +05:30
marination
fa9b327501 chore: Validate 'alternative_to' field values, must be a valid non-alterntaive item from table 2023-01-30 16:27:01 +05:30
Dany Robert
d69c839369 chore: linting issues 2023-01-30 10:45:08 +00:00
Dany Robert
1f6ab86a65 feat(gp): test for inv and dn related via so 2023-01-30 10:35:43 +00:00
marination
94cacb60de feat: Filter rows to be mapped on server side mapping function
- Pass dialog selections to `make_sales_order`
- Map either original item or its alternative depending on mapping
- Only qty check for simple rows (without alternatives and not an alternative itself)
2023-01-30 13:54:30 +05:30
s-aga-r
6b781d78e0 fix: amount in Material Request 2023-01-30 12:51:59 +05:30
Deepesh Garg
a34a1f8fd2 fix: Amount validation in Payment Request against Purchase Order (#33855)
fix: Amount validation in Payment Request againt Purchase Order
2023-01-29 21:34:28 +05:30
Deepesh Garg
faecf3ee40 fix: Lead to customer creation (#33859) 2023-01-29 21:25:49 +05:30
Deepesh Garg
6674edface chore: Resize numeric and date columns (#33858) 2023-01-29 21:25:26 +05:30
Deepesh Garg
428b099f63 fix: Ignore linked JE on JE cancellation (#33852) 2023-01-29 17:27:17 +05:30
Deepesh Garg
8abe0ce0ec fix: Currency symbol for tax withholding net total field (#33850)
* fix: Currency symbol for tax withholding net total field

* chore: Update display depends on property
2023-01-29 17:08:11 +05:30
ruthra kumar
fee0ca8cd9 perf: reduce memory usage by paging through records
While migrating GL entries to Payment Ledger, page through records using
primary key to reduce memory usage.
2023-01-29 15:27:01 +05:30
ruthra kumar
f270880735 fix: double salutation on quotation print (#33834)
'lead_name' always has salutation.
2023-01-28 18:17:25 +05:30
rohitwaghchaure
1b967f37af Merge pull request #33845 from rohitwaghchaure/fixed-item-not-fetching-issue
fix: item rate not fetching
2023-01-28 15:10:02 +05:30
Rohit Waghchaure
0d7f98b496 fix: item rate not fetching 2023-01-28 13:51:33 +05:30
Sabu Siyad
9e50aa4833 feat(pos): multiple item prices (#33005)
* fix(pos): multiple item prices

feat: show uom with product price
feat: multiple item (variant) depending on uom

Signed-off-by: Sabu Siyad <hello@ssiyad.com>

* feat(pos): consider uom for new item

Signed-off-by: Sabu Siyad <hello@ssiyad.com>

* feat(pos): uom based stock display

Signed-off-by: Sabu Siyad <hello@ssiyad.com>

* use `//` instead of `math.floor()`

Signed-off-by: Sabu Siyad <hello@ssiyad.com>

* feat(pos): uom by barcode

Signed-off-by: Sabu Siyad <hello@ssiyad.com>

* fix: replace `is not` with `!=`

Signed-off-by: Sabu Siyad <hello@ssiyad.com>

* fix(pos): barcode_info `next()`: fallback

Signed-off-by: Sabu Siyad <hello@ssiyad.com>

* chore: format

Signed-off-by: Sabu Siyad <hello@ssiyad.com>

* Update erpnext/selling/page/point_of_sale/point_of_sale.py

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>

* chore: un-ignore unused local variable

Signed-off-by: Sabu Siyad <hello@ssiyad.com>

---------

Signed-off-by: Sabu Siyad <hello@ssiyad.com>
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-01-28 10:28:31 +05:30
Deepesh Garg
3598bcc9a8 chore: ERPNext setup wizard cleanup (#33675)
* chore: ERPNext setup wizard cleanup

* chore: Remove default website

* chore: Remove flaky tests

* chore: remove unwanted tests
2023-01-27 14:40:39 +05:30
ruthra kumar
9dd6b3c950 Merge pull request #33835 from ruthra-kumar/skip_validation_on_migration
fix(patch): validation error on cost center allocation migration
2023-01-27 13:40:57 +05:30
ruthra kumar
de10f2dc00 fix(patch): validation error on cost center allocation migration
If Distributed cost centers have GL postings on patch run date,
patch failes with valiation error.
2023-01-27 12:08:18 +05:30
Sagar Vora
7e592fdf91 Merge pull request #33831 from dj12djdjs/perf-update-items
perf: show update items dialog
2023-01-27 04:17:39 +00:00
Devin Slauenwhite
a835c1a418 perf: show update items dialog 2023-01-26 16:53:05 -05:00
ruthra kumar
b31b850db8 fix: disfuctional cost center filter on Journal Entries (#33815)
* fix: missing cost_center filter for journal entries

* test: cost center filter on invoices, journals and payments
2023-01-26 20:26:21 +05:30
Vishal Dhayagude
c5ca8d74c4 fix: GST Category validation broken for pos unregistered customer who dont have address. (#33800)
* fix: GST Category validation is given for pos customer
2023-01-26 15:45:51 +05:30
marination
cef7dfd0b4 feat: Dialog to select alternative item before creating Sales order
- Users can leave the row blank in the dialog if original item is to be used
- Else users can select an alternative item against an original item
- In the document, users must check `Is Alternative Item` if needed and also specify which item it is an altenrative to since there are no documented mappings
2023-01-26 14:36:25 +05:30
Anand Baburajan
e3d7426b47 Merge pull request #33823 from AnandBaburajan/fix_translations
chore: remove broken translation
2023-01-26 13:46:16 +05:30
anandbaburajan
21f425660d chore: remove broken translation 2023-01-26 13:15:01 +05:30
Ankush Menat
33b68552f1 chore: remove broken translation
[skip ci]
2023-01-25 17:35:23 +05:30
Daizy Modi
da323cbb40 fix: use correct filter name in item_query (#33814) 2023-01-25 17:32:21 +05:30
Sagar Vora
41222659a6 Merge pull request #33813 from frappe/revert-33810-fix-quality-inspection-item-query
Revert "fix: use correct filter name in reports"
2023-01-25 10:50:03 +00:00
Sagar Vora
1f4fa90072 Revert "fix: use correct filter name in reports" 2023-01-25 16:19:44 +05:30
Sagar Sharma
58dab9ca8b Merge pull request #33810 from resilient-tech/fix-quality-inspection-item-query
fix: use correct filter name in reports
2023-01-25 16:15:04 +05:30
Daizy Modi
def759d2e8 fix: use correct filter name in reports 2023-01-25 15:57:39 +05:30
marination
f19eadab9a feat: Consider filtered items table in JS for totals computation
- Set `_items` as filtered rows if quotation else the entire table. Set at entry point of JS API
- Use `_items` instead of `items` to compute taxes and charges. Exclude alternative item rows
2023-01-25 13:10:03 +05:30
Devin Slauenwhite
a504b6eac0 fix: make title field readonly 2023-01-24 18:21:08 -05:00
Rohit Waghchaure
92d857d49c fix: purchase invoice performance issue 2023-01-24 22:32:07 +05:30
marination
91982d1e4f feat: Filter out alternative item rows in taxes and totals for Quotation
- Added a Quotation Item field `is_alternative_item`
- Use filtered rows for taxes and totals computation
2023-01-24 18:03:53 +05:30
Sagar Sharma
a067a904a1 Merge pull request #33797 from s-aga-r/fix-sco-status
chore: add `Cancelled` status in SCO `get_indicator`
2023-01-24 17:33:57 +05:30
Sagar Sharma
302f5e27be Merge branch 'develop' into fix-sco-status 2023-01-24 17:33:29 +05:30
s-aga-r
840f9d8987 chore: add Cancelled status in SCO get_indicator 2023-01-24 17:30:37 +05:30
rohitwaghchaure
a5478c61af Merge pull request #33790 from rohitwaghchaure/fix-web-supplier-quotation-from-rfq
fix: web supplier quotation
2023-01-24 15:59:04 +05:30
Raffael Meyer
d155042edd ci: documentation helper (#33757)
refactor: documentation helper
2023-01-24 11:42:44 +05:30
Anand Baburajan
84383087a6 Merge pull request #33789 from AnandBaburajan/update_translations_for_naming_series_error
chore: update translations for naming series error
2023-01-23 18:48:10 +05:30
anandbaburajan
4e6066f929 chore: fix translations 2023-01-23 18:07:32 +05:30
Rohit Waghchaure
7800db7c0d fix: web supplier quotation 2023-01-23 14:21:10 +05:30
Anand Baburajan
7d5df407c4 Merge branch 'develop' into update_translations_for_naming_series_error 2023-01-23 14:19:39 +05:30
anandbaburajan
bbde1f611f chore: update translations for naming series error 2023-01-23 14:16:31 +05:30
s-aga-r
9ae3a54ce9 chore: add method get_picked_items_details() 2023-01-23 13:48:26 +05:30
rohitwaghchaure
b3a216c8f8 Merge pull request #33785 from rohitwaghchaure/get-items-from-transit-entry
feat: get items from Transit Stock Entry
2023-01-23 13:03:53 +05:30
Rohit Waghchaure
62141b0b63 feat: get items from Transit Stock Entry 2023-01-23 12:01:57 +05:30
Deepesh Garg
a3c89dbc10 fix: TDS deduction in payment entry (#33747)
* fix: TDS deduction in payment entry
2023-01-22 23:31:19 +05:30
Xeanth
ad437fd5ba fix: use stock qty to calculate POS reserved stock (#33735) 2023-01-22 18:06:01 +05:30
Sagar Sharma
7a8e89e2fe fix: incorrect rate and amount in MR Item (#33547)
* fix: incorrect `rate` and `amount` in MR Item
2023-01-22 18:04:13 +05:30
Sagar Sharma
72be489b1b Merge pull request #33778 from barredterra/fix-missing-const
fix: missing constant definition
2023-01-21 22:28:49 +05:30
barredterra
547d37b1db fix: missing constant definition 2023-01-21 17:29:43 +01:00
Deepesh Garg
2f03dcb5b6 fix: Better budget exceeding validation messages (#33713)
* fix: Better budget exceeding validation messages

* chore: remove unwanted changes
2023-01-21 19:33:14 +05:30
s-aga-r
57c3216683 refactor: rewrite get_available_item_locations_for_serial_and_batched_item query in QB 2023-01-21 14:05:51 +05:30
s-aga-r
5b76e8b193 refactor: rewrite get_available_item_locations_for_serialized_item query in QB 2023-01-21 12:45:39 +05:30
s-aga-r
58dd40a2d7 refactor: rewrite get_available_item_locations_for_other_item query in QB 2023-01-21 12:15:45 +05:30
rohitwaghchaure
f6f64083d2 Merge pull request #33760 from rohitwaghchaure/allow-to-change-bom-in-sco
fix: not able to change default BOM in the Subcontracting Order
2023-01-21 12:04:50 +05:30
s-aga-r
29bf787313 refactor: rewrite get_picked_items_qty query in QB 2023-01-21 11:28:23 +05:30
ruthra kumar
4cbd63edbf Merge pull request #33710 from openrefactory/patch-2
Removed an unnecessary check in code which always evaluates to true
2023-01-21 09:41:04 +05:30
OpenRefactory, Inc
49aed7ff69 fix: removed an unnecessary check which always evaluates to true 2023-01-21 06:15:51 +05:30
Kevin Shenk
e4bceaaf66 feat: Copy project_name, from_time, to_time from timesheet details to sales invoice (#33726)
feat: Copy project_name, from_time, to_time from timesheet details to sales invoice
2023-01-20 23:39:37 +05:30
rohitwaghchaure
b5d2eedfa6 Merge pull request #33759 from rohitwaghchaure/fix-incorrect-actual-qty-for-packed-item
fix: incorrect actual qty for the packed item
2023-01-20 23:38:55 +05:30
Rohit Waghchaure
11b2994fe8 fix: not able to change default BOM in the Subcontracting Order 2023-01-20 23:27:49 +05:30
Rohit Waghchaure
02566a02a8 fix: incorrect actual qty for the packed item 2023-01-20 22:38:56 +05:30
rohitwaghchaure
d462d6de06 Merge pull request #33595 from vishdha/fg_based_operating_cost
feat: Add operating cost based on bom quanity without creating job card
2023-01-20 22:36:42 +05:30
Dany Robert
1e607cd4c7 fix(pricing rule): free item duplication (#33746)
* fix(pricing rule): free item duplication

* chore: linting issues
2023-01-20 20:07:37 +05:30
Deepesh Garg
597ef0a498 fix: Short closed order, receipt and delivery note status on cancellation (#33743)
* fix: Short closed order, receipt and delivery note status on cancellation

* test: Cancelled status check
2023-01-20 19:44:06 +05:30
Raffael Meyer
327b6fdb32 fix: calculate correct amount for qty == 0 (#33739) 2023-01-20 19:35:27 +05:30
Sabu Siyad
a94aa7a79f fix(ecommerce): breadcrumb: fallback to /all-products (#33718)
* fix(ecommerce): breadcrumb: fallback to `/all-products`

* fix(item_group): use `==` instead of `is`

* test(ecommerce): breadcrumb
2023-01-20 18:54:54 +05:30
Ritwik Puri
17045f88a1 fix: use hash based naming for tax withheld vouchers child table (#33643) 2023-01-20 18:53:39 +05:30
Dany Robert
ef90e24931 chore: linting issue 2023-01-19 10:25:05 +00:00
Dany Robert
e8e20da78e fix(gp): fetch buying amount from dn related to so 2023-01-19 09:39:43 +00:00
Sagar Sharma
cceb7922a5 Merge pull request #33619 from SvbZ3r0/item-attr-abbr-lowercase
fix: rewrite logic for duplicate check in Item Attribute
2023-01-19 13:27:43 +05:30
Sagar Sharma
333b2ae721 Merge branch 'develop' into item-attr-abbr-lowercase 2023-01-19 12:55:49 +05:30
rohitwaghchaure
ecfebfec57 Merge pull request #33723 from rohitwaghchaure/fixed-issue-of-item-variant
fix: don't add template item in sales/purchase transaction
2023-01-19 12:42:04 +05:30
Rohit Waghchaure
2c83fff1a1 fix: don't add template item in sales/purchase transaction 2023-01-18 23:29:06 +05:30
mergify[bot]
cc569c955f fix: the frappe throw message is corrected in the group task validation (#33698)
fix: the frappe throw message is corrected in the group task validation (#33698)
2023-01-18 21:47:22 +05:30
Sagar Sharma
60ec7b6cde Merge pull request #33679 from s-aga-r/refactor/qb/pick-list
refactor: rewrite `pick_list.py` queries in `QB`
2023-01-18 18:26:08 +05:30
Sagar Sharma
f89600aee8 Merge branch 'develop' into refactor/qb/pick-list 2023-01-18 17:52:23 +05:30
rohitwaghchaure
e8e21ea4b4 Merge pull request #33712 from rohitwaghchaure/fixed-stock_rbnb-error
fix: local variable 'stock_rbnb' referenced before assignment
2023-01-18 16:36:20 +05:30
Rohit Waghchaure
1de4742ffb fix: local variable 'stock_rbnb' referenced before assignment 2023-01-18 15:29:39 +05:30
Sagar Sharma
eee3bd2554 Merge branch 'develop' into refactor/qb/pick-list 2023-01-18 13:01:59 +05:30
Deepesh Garg
6b31c27ed6 fix: Missing constructor args in Bank Reco Tool (#33705) 2023-01-17 21:03:39 +05:30
Vishal Dhayagude
c4e1f81ccb Merge branch 'develop' into fg_based_operating_cost 2023-01-17 19:20:37 +05:30
Anand Baburajan
d7522d40c0 Merge pull request #33682 from AnandBaburajan/misc_asset_fixes
fix: handle asset depr entries posting failure, improve asset depr schedules cancel notes and fix asset repair link [develop]
2023-01-17 16:23:13 +05:30
Anand Baburajan
c6cfacc108 Merge branch 'develop' into misc_asset_fixes 2023-01-17 15:09:37 +05:30
Deepesh Garg
db9beb3cdd fix: Rate from LDC in TDS reports (#33699) 2023-01-17 14:53:24 +05:30
Vishal Dhayagude
f19212b5c8 Merge branch 'develop' into fg_based_operating_cost 2023-01-17 13:02:25 +05:30
Anand Baburajan
d97127bff2 Merge branch 'develop' into misc_asset_fixes 2023-01-17 12:57:22 +05:30
Sagar Sharma
eeed3356ac Merge branch 'develop' into refactor/qb/pick-list 2023-01-17 12:25:16 +05:30
rohitwaghchaure
e68c4e2aa8 Merge pull request #33695 from rohitwaghchaure/fixed-patch-item_reposting_for_incorrect_sl_and_gl
fix: patch item_reposting_for_incorrect_sl_and_gl
2023-01-17 12:18:34 +05:30
Rohit Waghchaure
dbde3a3421 fix: patch item_reposting_for_incorrect_sl_and_gl 2023-01-17 11:47:53 +05:30
Anand Baburajan
c4d3a8a600 Merge branch 'develop' into misc_asset_fixes 2023-01-17 11:21:37 +05:30
Ankush Menat
64f7f3a12a chore: ignore b028
Very high false positive count. 

[skip ci]
2023-01-17 10:56:55 +05:30
Sagar Sharma
1cadef97bf Merge branch 'develop' into refactor/qb/pick-list 2023-01-17 10:08:36 +05:30
Sagar Sharma
e4cf0dced8 Merge pull request #33690 from FHenry/dev_fix_bug_from_78b438f6
fix: Sales Order Connections Tabs do not show linked Material Request or "+" button  (intoduce by #33304)
2023-01-17 10:05:49 +05:30
Sagar Sharma
fb950417bf Merge branch 'develop' into dev_fix_bug_from_78b438f6 2023-01-17 10:04:36 +05:30
Deepesh Garg
0639d9e32a chore: Typo in payment reconciliation (#33686) 2023-01-17 08:06:30 +05:30
Florian HENRY
e19161a8ee fix: Sales ORder Connections on Material Request 2023-01-16 21:03:18 +01:00
anandbaburajan
86cf5c89ab chore: add depr_entry_posting_status in create_asset 2023-01-17 00:31:21 +05:30
anandbaburajan
cebb5a42f4 chore: add missing /n in options 2023-01-17 00:26:50 +05:30
Anand Baburajan
011a4c3faa Merge branch 'develop' into misc_asset_fixes 2023-01-17 00:00:09 +05:30
rohitwaghchaure
66ae807a26 Merge pull request #33684 from rohitwaghchaure/fixed-work-order-summary
feat: [minor] date type based on filter in Work Order Summary report
2023-01-16 23:57:43 +05:30
rohitwaghchaure
d6915df81d Merge pull request #33680 from rohitwaghchaure/refactor-picked-qty
refactor: picked qty in sales order item
2023-01-16 23:31:56 +05:30
Rohit Waghchaure
20c8873208 feat: provision to select date type based on filter 2023-01-16 23:29:13 +05:30
anandbaburajan
a144bb01fe chore: stying 2023-01-16 23:26:39 +05:30
Anand Baburajan
070bc8badd Merge branch 'develop' into misc_asset_fixes 2023-01-16 23:23:12 +05:30
anandbaburajan
cf7b43f7f0 fix: handle_post_depr_entries_fail, show error alert and send email 2023-01-16 23:10:02 +05:30
Rohit Waghchaure
1bcff80074 refactor: picked qty in sales order item 2023-01-16 22:50:16 +05:30
Devin Slauenwhite
179a31ed5e feat: disable currency exchange api. (#33593) 2023-01-16 21:00:10 +05:30
anandbaburajan
61cd0f98fd fix: asset repair link and improve notes 2023-01-16 18:35:40 +05:30
Vishal Dhayagude
352dcddd6d Merge branch 'develop' into fg_based_operating_cost 2023-01-16 17:02:31 +05:30
Sagar Sharma
1769b45d4b Merge branch 'develop' into refactor/qb/pick-list 2023-01-16 16:04:20 +05:30
s-aga-r
0ed6552655 refactor: rewrite pick_list.py queries in QB 2023-01-16 16:01:40 +05:30
Deepesh Garg
adaeba1554 fix(minor): Label updates in Statement of Accounts (#33639)
fix(minor): Label updates in Satement of Accounts
2023-01-16 14:03:54 +05:30
Deepesh Garg
312625fdc5 fix: Patch to update reference_due_date in Journal Entry (#33616) 2023-01-16 13:43:54 +05:30
ruthra kumar
9627b46ee7 Merge pull request #33661 from ruthra-kumar/performance_tuning_payment_reconciliation
perf: improve reconciliation performance for JE with 100s of accounts
2023-01-16 09:41:17 +05:30
ruthra kumar
56aa1866da Merge pull request #33663 from ruthra-kumar/attribute_error_on_repost_ple_tool
fix: attribute error while submitting Repost PLE
2023-01-16 09:36:22 +05:30
Raffael Meyer
dceef0397a fix: allow to create sales order from expired quotation (#33582) 2023-01-16 08:53:37 +05:30
ruthra kumar
be382054e5 revert: Reverting changes done on 33495 (#33662)
'ordered_qty' will not be fetched from `tabBin`
2023-01-16 08:50:39 +05:30
ruthra kumar
333907b7a5 Revert "fix: Updating SO throws ordered_qty not allowed to change after submission" (#33646) 2023-01-16 08:49:35 +05:30
Poruri Sai Rahul
8119442c94 FIX: Remove usage of "six.string_types" (#33603)
FIX: Remove usage of six.string_types

six is no longer a dependency
2023-01-16 08:47:28 +05:30
Sagar Sharma
9069643504 Merge pull request #33664 from s-aga-r/so-ref-in-pick-list
chore: `Sales Order` link in `Pick List`
2023-01-15 23:04:53 +05:30
s-aga-r
b3759890d7 chore: Sales Order link in Pick List 2023-01-15 21:09:16 +05:30
ruthra kumar
2c50f43cdd fix: attribute error while submitting Repost PLE 2023-01-15 20:51:54 +05:30
ruthra kumar
828eaf0930 fix: minor filter issue while reconciliation tool from bench console 2023-01-15 18:09:51 +05:30
ruthra kumar
11cf694d9a perf: improve reconciliation speed on JE's with 1000's of rows
1. No need to keep old PLE's on reconciliation.
2. Added Validation to catch debit-credit mismatch on JE's
3. Only update outstanding amount for newly reconciled invoices
2023-01-15 17:51:46 +05:30
Raffael Meyer
67cf7e1728 refactor: use DocStatus (#33594) 2023-01-15 17:34:16 +05:30
Deepesh Garg
906ad10d16 fix: Return against internal purchase invoice (#33635) 2023-01-15 17:32:57 +05:30
Sagar Sharma
bfbc9ea8f7 Merge branch 'develop' into item-attr-abbr-lowercase 2023-01-15 12:55:01 +05:30
Sagar Sharma
242af681e9 Merge pull request #33651 from s-aga-r/fix/scr-rm-cost
fix: zero rm-cost in SCR
2023-01-14 23:11:12 +05:30
s-aga-r
f70d757b82 fix: zero rm-cost in SCR 2023-01-14 22:24:18 +05:30
Vishal Dhayagude
736afdf85a Merge branch 'develop' into fg_based_operating_cost 2023-01-13 10:03:50 +05:30
Sagar Sharma
c2b3843d80 Merge branch 'develop' into item-attr-abbr-lowercase 2023-01-13 00:49:21 +05:30
Ritwik Puri
e22d56484d chore: reuse doc object in test_pick_list_grouping_before_print (#33636) 2023-01-13 00:47:26 +05:30
Deepesh Garg
75e52d7108 Merge pull request #33608 from AnandBaburajan/fixed_asset_report_asset_value
fix: asset value in fixed asset register
2023-01-12 22:59:19 +05:30
Vishal Dhayagude
d63258ee9b Merge branch 'develop' into fg_based_operating_cost 2023-01-12 21:50:09 +05:30
unknown
2ca4d3fb71 fix: linting 2023-01-12 20:53:12 +05:30
Anand Baburajan
29088e1777 Merge branch 'develop' into fixed_asset_report_asset_value 2023-01-12 20:30:39 +05:30
Deepesh Garg
afb33f2049 Merge pull request #33271 from sonali8848/filters-on-bank-reconciliation
feat: Date filters on bank reconciliation tool
2023-01-12 18:25:05 +05:30
Deepesh Garg
232726288a chore: fix fieldnames and order 2023-01-12 17:44:07 +05:30
Ritwik Puri
cfb0bb1eaa fix: only group similar items in print format if group_same_items is checked in pick list (#33627)
* fix: only group similar items if group same items is checked in pick list

* test: non grouping of locations if group_same_items is false

Co-authored-by: Sagar Sharma <sagarsharma.s312@gmail.com>
2023-01-12 17:25:50 +05:30
ruthra kumar
e0db2670f9 Merge pull request #33622 from ruthra-kumar/fix_change_after_submission_on_error
fix: Updating SO throws ordered_qty not allowed to change after submission
2023-01-12 16:59:08 +05:30
Sagar Sharma
9ed7594f6e Merge pull request #33621 from s-aga-r/fix/validation/scr
chore: subcontracting validations
2023-01-12 15:49:30 +05:30
s-aga-r
b26e96cdf4 chore: linter 2023-01-12 13:41:53 +05:30
ruthra kumar
391f42db04 fix: Updating SO throws ordered_qty not allowed to change after submission 2023-01-12 13:18:03 +05:30
s-aga-r
f028bd6e69 fix: validate accepted and rejected qty in SCR Item 2023-01-12 12:23:40 +05:30
s-aga-r
a0e2a93f3f chore: update error msgs for Subcontracted PO 2023-01-12 12:09:28 +05:30
s-aga-r
6878f40d1d chore: add row-index in error msgs 2023-01-12 12:02:00 +05:30
s-aga-r
434aa594d5 fix: ZeroDivisionError: float division by zero in SCR 2023-01-12 11:49:41 +05:30
unknown
974e12c837 fix: rewrite logic for duplicate check in Item Attribute
Previously, Item Attribute values were not checked for case-insensitive duplicates, and Item tttribute abbreviations were forced to be uppercase. This commit fixes both problems.
2023-01-12 07:44:57 +05:30
Vishal Dhayagude
467a2b5cb4 Merge branch 'develop' into fg_based_operating_cost 2023-01-11 22:30:36 +05:30
Vishal
694fc3e20c fix: hide with_operation on selection on fg_based and vice versa 2023-01-11 18:52:30 +05:30
Sagar Sharma
9ab8aa49d6 Merge pull request #33611 from vorasmit/fix-diff-value
fix: better comparision of `difference_value` of Stock and Account
2023-01-11 14:52:49 +05:30
Sagar Sharma
887ae1c434 Merge branch 'develop' into fix-diff-value 2023-01-11 14:01:51 +05:30
Smit Vora
be05aea101 fix: better comparision of difference value between stock and account 2023-01-11 05:21:13 +00:00
anandbaburajan
aa1f2a7297 fix: asset value in fixed asset register 2023-01-10 23:05:09 +05:30
Smit Vora
e0f5ecdad6 fix: RFQ emails not sent with pdf attachment (#33604) 2023-01-10 20:40:12 +05:30
vr-greycube
0f0bc9a462 fix: customer selection not mandatory in purchase invoice to fetch item details (#33572) 2023-01-10 20:26:33 +05:30
Deepesh Garg
0ed938a490 fix: Incorrect exchange rate in payment entries (#33481)
* fix: Incorrect exchange rate in payment entries

* test: Update failing tests
2023-01-10 20:12:43 +05:30
rohitwaghchaure
58ad79d3e8 Merge pull request #33597 from rohitwaghchaure/do-not-check-other-warehouse
fix: don't check other warehouse ledgers to calculate valuation rate
2023-01-10 13:56:10 +05:30
Vishal
a5cbdea8e4 fix: minor change in bom.js added 2023-01-10 13:40:12 +05:30
Rohit Waghchaure
ef2bf3c223 fix: don't check other warehouse ledgers to calculate valuation rate 2023-01-10 10:59:50 +05:30
Ankush Menat
8a56df695d perf: Drop name part from posting sort index (#33551) 2023-01-10 09:54:15 +05:30
Vishal
c51f9e0a97 fix: bom.json updated 2023-01-10 07:48:26 +05:30
Vishal
f0c0a64984 fix: test case added for FG_BASED OPERTING COST 2023-01-10 07:43:28 +05:30
Vishal
ddc0127e05 fix: minor changes added 2023-01-10 07:43:20 +05:30
Vishal
b559245f2a feat: Add operating cost based on bom quanity without creating job card 2023-01-10 07:43:05 +05:30
rohitwaghchaure
59628f1934 Merge pull request #33579 from rtdany10/repack-fg-valuation
fix(stock entry): wrong valuation rate in repack
2023-01-10 00:05:56 +05:30
rohitwaghchaure
a424acbfcb Merge pull request #33577 from rohitwaghchaure/timeout-error-in-purchase-invoice
fix: Timeout error while saving the purchase invoice
2023-01-10 00:01:15 +05:30
rohitwaghchaure
461f8e7724 Merge pull request #33590 from frappe/revert-33347-fb_based_operating_cost
Revert "feat: Add operating cost based on bom quanity without creating job card"
2023-01-09 23:37:13 +05:30
rohitwaghchaure
d749c4aac2 Revert "feat: Add operating cost based on bom quanity without creating job card" 2023-01-09 23:35:11 +05:30
rohitwaghchaure
20fe1875e7 Merge pull request #33347 from vishdha/fb_based_operating_cost
feat: Add operating cost based on bom quanity without creating job card
2023-01-09 23:31:41 +05:30
Gughan Ravikumar
4d5067d6d4 fix(accounts): currency fields no longer read as strings by validation function in Payment Entry (#33535)
explicitly cast paid_amount and received_amount to float in the Payment Entry set_unallocated_amount validation function
2023-01-09 23:26:51 +05:30
ruthra kumar
bbe5e5d9d6 fix: incorrect warehouse and selling amount on bundled products (#33549) 2023-01-09 22:45:43 +05:30
Sagar Sharma
dd3b79b511 Merge pull request #33562 from ruthra-kumar/better_handling_of_duplicate_bundle_items
fix: better handling of duplicate bundle items
2023-01-09 22:22:57 +05:30
Devin Slauenwhite
6bc8bb26b6 fix: customer/supplier quick entry dialog (#33496)
* fix: readonly primary contact fields.

* refactor: supplier and customer quick entry form into common class.
2023-01-09 22:22:19 +05:30
Rohit Waghchaure
ec171fc7c1 test: test case to check disable last purchase rate 2023-01-09 22:02:35 +05:30
Sagar Sharma
b56c1ed050 Merge branch 'develop' into better_handling_of_duplicate_bundle_items 2023-01-09 21:48:48 +05:30
Deepesh Garg
f056e9e7c5 Merge pull request #33569 from ruthra-kumar/patch_to_update_new_je_type_in_property_setters
chore: patch property setters for JE with new entry type
2023-01-09 21:01:52 +05:30
Deepesh Garg
57a6c37833 Merge pull request #32933 from AnandBaburajan/asset_depreciation_schedule
feat: separating depreciation schedule from assets into a new doc
2023-01-09 20:47:21 +05:30
sonali
917b2190aa fix: remove comments 2023-01-09 20:07:24 +05:30
Ankush Menat
fa4af2acce refactor: convert heatmap queries to QB (#33581)
Uses new `UnixTimestamp` function, don't backport.
2023-01-09 20:00:22 +05:30
safvanhuzain
99f5e869e0 fix(stock entry): wrong valuation rate in repack 2023-01-09 13:11:37 +00:00
Rohit Waghchaure
05df8579cd fix: linters issue 2023-01-09 18:23:22 +05:30
Ankush Menat
7ee151880a chore: instructions for running forks
[skip ci]
2023-01-09 18:16:04 +05:30
Rohit Waghchaure
d1d4671320 feat: provision to disable get last purchase rate
fix: set_incoming_rate condition
2023-01-09 18:10:52 +05:30
Rohit Waghchaure
7249657d15 fix: timeout error in the Purchase Invoice 2023-01-09 14:53:54 +05:30
Raffael Meyer
a4cb0313dd chore: test with wkhtmltopdf 12.6 (#33554)
* chore: test with latest wkhtmltopdf

* chore: check ubuntu version

* ci: check exit code of wk install

Co-authored-by: Ankush Menat <ankush@frappe.io>
2023-01-09 14:27:34 +05:30
Ankush Menat
1ad1fc4c7d ci: bump node in release workflow (#33574)
[skip ci]
2023-01-09 13:25:05 +05:30
rohitwaghchaure
44f32f7521 Merge pull request #33568 from dj12djdjs/fix-manufacture-field-tab
fix: move `include_item_in_manufacturing` into Manufacturing Tab
2023-01-09 12:25:40 +05:30
ruthra kumar
789e448f0e chore: patch property setters for JE with new entry type 2023-01-08 11:45:28 +05:30
Devin Slauenwhite
e35ac4f8c2 fix: move include in manufacturing to manufacturing tab. 2023-01-07 22:47:16 -05:00
ruthra kumar
c717e87c9e fix: better handling of duplicate bundle items 2023-01-06 16:21:20 +05:30
rohitwaghchaure
525f054c45 Merge pull request #33548 from rohitwaghchaure/fixed-incorrect-wo-status
fix: incorrect status in the work order
2023-01-06 16:01:24 +05:30
Rohit Waghchaure
b0baba84a0 fix: incorrect status in the work order 2023-01-06 14:16:18 +05:30
ruthra kumar
51b082b43c Merge pull request #33537 from ruthra-kumar/sales_partner_in_ar_report
refactor: Sales Partner column in AR and AR Summary Report
2023-01-06 12:07:50 +05:30
Vishal
9fd1c3efb4 fix: test case added for FG_BASED OPERTING COST 2023-01-06 11:18:09 +05:30
Vishal
6b0b49ee3f fix: minor changes added 2023-01-06 11:18:09 +05:30
Vishal
bc1bdd58a7 feat: Add operating cost based on bom quanity without creating job card 2023-01-06 11:18:09 +05:30
Sagar Sharma
f4a1218467 Merge pull request #33543 from s-aga-r/fix/github-issue/25162
chore: enable `No Copy` attribute for `route` in Item Group
2023-01-05 13:01:53 +05:30
s-aga-r
348dc32514 chore: enable No Copy attribute for route in Item Group 2023-01-05 12:25:50 +05:30
rohitwaghchaure
f6da6ece0a Merge pull request #33524 from rohitwaghchaure/revamp-process-loss-feature
refactor: revamp process loss feature & added tab breaks
2023-01-04 18:37:32 +05:30
ruthra kumar
ee94127974 refactor: Sales Partner column in AR and AR Summary Report 2023-01-04 12:41:02 +05:30
Anand Baburajan
3ae47ab32c Merge branch 'develop' into asset_depreciation_schedule 2023-01-04 01:34:08 +05:30
Rohit Waghchaure
524c0994e0 test: test cases for process loss 2023-01-03 22:47:52 +05:30
Deepesh Garg
c78399c618 fix: Missing opening entry in general ledger (#33519) 2023-01-03 21:35:03 +05:30
Deepesh Garg
1a83a67d41 fix: Get payment entry button not visible in Bank Clearance doc (#33518) 2023-01-03 21:34:49 +05:30
Rohit Waghchaure
ae039777f9 refactor: revamp process loss feature & added tab breaks 2023-01-03 19:05:41 +05:30
Sagar Sharma
d3b74a868e Merge pull request #33514 from s-aga-r/fix/github-issue/33417
fix: set `supplier` details while mapping SE(Send to Subcontractor)
2023-01-03 18:57:07 +05:30
Sagar Sharma
9f59330fa9 Merge branch 'develop' into fix/github-issue/33417 2023-01-03 18:51:27 +05:30
Deepesh Garg
a3ab8f973a fix: Deferred revenue date comparison (#33515) 2023-01-03 17:51:41 +05:30
s-aga-r
751bdc98ed fix: set supplier details while mapping SE(Send to Subcontractor) 2023-01-03 17:17:23 +05:30
Deepesh Garg
9a3d947e89 fix: Exchange gain and loss booking on multi-currency invoice reconciliation (#32900)
* fix: Exchange gain and loss booking on multi-curreny invoice reconciliation

* test: Update test cases

* chore: Ignore SQL linting rule

* chore: Joural Entry for exchange gainand loss booking

* chore: Journal entry for exchange gain loss booking

* test: Update test case

* chore: Default exchange gain and loss account
2023-01-03 16:55:15 +05:30
Anand Baburajan
d9c91fa072 Merge branch 'develop' into asset_depreciation_schedule 2023-01-03 15:10:07 +05:30
anandbaburajan
312e51e8b2 chore: more refactoring and adding test for duplicate asset_depr_schedule 2023-01-03 15:09:04 +05:30
anandbaburajan
adb5249257 chore: fix patch 2023-01-03 13:03:12 +05:30
anandbaburajan
7b6b5ae581 chore: refactoring patch 2023-01-03 09:21:08 +05:30
anandbaburajan
e501c2db51 chore: just testing patch 2023-01-02 21:11:53 +05:30
anandbaburajan
357c17214d chore: fix patch 2023-01-02 20:32:29 +05:30
rohitwaghchaure
6a4e25c1f9 Merge pull request #33504 from rohitwaghchaure/fixed-incorrect-picked-qty-in-so
fix: [concurrency issue] incorrect picked qty in sales order
2023-01-02 20:12:05 +05:30
Rohit Waghchaure
aba83849a6 fix: [concurrency issue] incorrect picked qty in sales order 2023-01-02 18:46:22 +05:30
Anand Baburajan
72c2e77a5d Merge branch 'develop' into asset_depreciation_schedule 2023-01-02 17:07:58 +05:30
anandbaburajan
7c5168eeac chore: allow manually submitting and cancelling asset depr schedule 2023-01-02 17:07:28 +05:30
ruthra kumar
914b23038c refactor: Exchange rate revaluation to handle accounts with zero account balance (#33165)
* refactor: new type for JE - Exchange Gain or Loss

* refactor: skip few validations for Exchanage Gain Or Loss type Jour

* refactor: ERR create 2 journals for handling zero and non-zero compa

1. Additional check box accounts table to identify accounts with zero balance
2. Accounts with zero balance only in either of the 2 currencies will be handled on separate Journal

* refactor: skips few validation for allowing 0 debit/credit

* fix: General Ledger presentaion currency

* test: fix test case in general ledger

* test: fix failing test case in AR report
2023-01-02 14:33:14 +05:30
ruthra kumar
23fbe86d51 refactor: Show Balance in COA based on Accounts Settings 2023-01-02 13:32:01 +05:30
ruthra kumar
1b78fae6fc refactor: show balance checkbox in Accounts Settings 2023-01-02 13:31:56 +05:30
Sagar Sharma
a7b011aed4 Merge pull request #33444 from s-aga-r/fix/github-issue/28766
fix: consider child nodes while getting bin details
2023-01-02 11:54:11 +05:30
s-aga-r
b425c2d7ec Merge branch 'develop' into fix/github-issue/28766 2023-01-02 11:25:13 +05:30
Sagar Sharma
332f4dc028 Merge pull request #33495 from dj12djdjs/fix-get-bin-details
fix(stock): missing ordered_qty in get_bin_details
2023-01-02 11:14:25 +05:30
Sagar Sharma
e18b0ebe92 Merge branch 'develop' into fix-get-bin-details 2023-01-02 10:49:29 +05:30
Sagar Sharma
49025db33c Merge branch 'develop' into fix/github-issue/28766 2023-01-02 10:27:42 +05:30
Marc de Lima Lucio
3c393bfdc5 fix: javascript: execution blocked by undefined route options (#33405)
Some implementations of DocField.get_route_options_for_new_doc() returned no value instead of an empty object in some cases, which caused a JavaScript error.
2023-01-02 09:18:25 +05:30
MOHAMMED NIYAS
d054f37602 feat: calculate hours (#33464)
* feat: calculate hours

* chore: Linting Issues

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-01-02 09:17:14 +05:30
Sabu Siyad
010718ffed fix(ecommerce/cart): explicitly set frappe.boot (#33431)
related: https://github.com/frappe/frappe/pull/18323

Signed-off-by: Sabu Siyad <hello@ssiyad.com>

Signed-off-by: Sabu Siyad <hello@ssiyad.com>
2023-01-02 08:58:01 +05:30
Devin Slauenwhite
98c39c4f5f fix: update payment entry references (#33274)
* fix: set_amounts after deductions and losses are set

* test: difference_amount changes after update_references_in_payment_entry

* chore: linter

* fix: use kwargs instad of destructing a dict

[skip ci]

* fix(test): test payment entry difference_amount after payment reconciliation.
2023-01-02 08:55:12 +05:30
Sagar Sharma
7126d71627 Merge branch 'develop' into fix/github-issue/28766 2023-01-01 22:24:47 +05:30
Devin Slauenwhite
239a5f8bf4 test: get_item_details contains bin details 2022-12-31 15:41:07 -05:00
Devin Slauenwhite
8d62cdfd5f fix: add missing 'ordered_qty' to get_bin_details 2022-12-31 14:14:25 -05:00
Deepesh Garg
bb4725e9b5 Merge pull request #33488 from deepeshgarg007/multi_currency_bank_reco
fix: Multi-currency issues in Bank Reconciliation Tool
2022-12-31 13:05:25 +05:30
sonali
12822f7c36 fix: data format 2022-12-30 14:06:19 +05:30
Deepesh Garg
ad53ecf2b4 fix: Multi-currency issues in Bank Recociliation Tool 2022-12-30 13:37:41 +05:30
Gughan Ravikumar
48a9cd5ef3 fix: allow arbitary items in Quotation ans Sales Order (#33430)
fix: allow arbitary items in Quotation ans Sales Order
2022-12-30 13:16:40 +05:30
rohitwaghchaure
6e1ef4f3d0 Merge pull request #33487 from frappe/revert-33387-audit-to-fix-incorrect-valuation-entry
Revert "fix: daily scheduler to identify and fix stock transfer entries having incorrect valuation"
2022-12-30 12:58:36 +05:30
rohitwaghchaure
728dc1acf4 Revert "fix: daily scheduler to identify and fix stock transfer entries having incorrect valuation" 2022-12-30 11:08:31 +05:30
Sagar Sharma
d072169340 Merge branch 'develop' into fix/github-issue/28766 2022-12-29 16:38:53 +05:30
s-aga-r
c3911a592a chore: use frappe.qb instead of frappe.db.get_value 2022-12-29 16:38:08 +05:30
sonali
d65243eb65 feat: consolidated auto bank reconciliation
Added a button of Auto Reconcile, to reconcile the bank entries as per the matching reference number with the bank transaction and count of transactions reconciled message will be pop up on clicking the auto reconcile button.
2022-12-29 16:12:25 +05:30
s-aga-r
c716dcc01e fix: consider child nodes while getting bin details 2022-12-29 14:01:42 +05:30
sonali
c764f14f53 fix: pre-commit 2022-12-29 13:58:06 +05:30
sonali
35c29e0226 fix: pre-commit 2022-12-29 13:45:15 +05:30
sonali
f1810803e1 fix: passing from_date and to_date filters in test cases
passing from_date and to_date filters in  test_linked_payments and test_debit_credit_output  for unit testing
2022-12-29 13:07:06 +05:30
sonali
e2614b8a21 fix: pre-commit 2022-12-29 12:21:45 +05:30
sonali
3aaa2f5326 fix: filtered as per reference date
On bank reconciliation, transactions will be filtered as per date selected in 'from_date' and 'to_date' fields , In dialog, all the bank entries will  be fetched as per the posting date selected and if filtered by reference date checkbox is tick then then there will be two fields 'from_reference_date' and 'to_reference_date' then all bank entries in dialog box came as per reference date, selected. And by default journal entry checkbox is tick.
Also sorted the bank transactions and bank entries as per ascending order date wise.
2022-12-29 12:05:22 +05:30
Deepesh Garg
617518389a fix: Conversion factor error for invoices without item code (petty expenses) (#32714)
* fix: Set default uom conversion factor to 1 for invoices

* chore: set default conversion_factor as 1

* chore: remove print statements
2022-12-29 10:41:36 +05:30
Devin Slauenwhite
123920d0bc feat: add after_refresh hook to item dashboard (#33372)
* fix: return promise

* fix: use after_refresh hook instead of promise

# Because there is already a before_refresh hook. I think it makes sense to do the same for after.
2022-12-29 10:31:26 +05:30
ruthra kumar
e3a0ce5d63 fix: use base_net_amount in case of missing stock qty (#33457) 2022-12-29 09:34:51 +05:30
Dany Robert
cabaed9ed2 fix(pricing rule): consider child tables in condition (#33469) 2022-12-28 18:05:55 +05:30
Sagar Sharma
882f92e732 Merge pull request #33465 from s-aga-r/fix/po-fg_item_qty
fix: `fg_item_qty` in non-subcontracted PO
2022-12-28 15:27:18 +05:30
s-aga-r
6f5824cb21 fix: fg_item_qty in non-subcontracted PO 2022-12-28 14:54:24 +05:30
Sabu Siyad
8e271fd719 feat(exotel): make use of CustomField in API (#33338)
* feat(exotel): pass kwargs for `make_a_call`

https://developer.exotel.com/api/make-a-call-api#call-agent

Signed-off-by: Sabu Siyad <hello@ssiyad.com>

* feat(exotel): map custom field to doctype

Signed-off-by: Sabu Siyad <hello@ssiyad.com>

Signed-off-by: Sabu Siyad <hello@ssiyad.com>
2022-12-28 08:11:28 +05:30
Deepesh Garg
0b75aa5390 fix: Default dimensions on fetching items from BOM (#33439) 2022-12-27 17:53:43 +05:30
Deepesh Garg
d2686ce75b fix: Multiple rows for same warehouse and batches in pick list (#33456) 2022-12-27 17:42:03 +05:30
anandbaburajan
21a09e7431 chore: fix patch 2022-12-27 15:01:42 +05:30
anandbaburajan
97f8588202 chore: fix patch name 2022-12-27 15:01:42 +05:30
anandbaburajan
c916fb0513 chore: fix module name in patch 2022-12-27 15:01:42 +05:30
anandbaburajan
57adcc0b03 chore: move patch to pre_model_sync 2022-12-27 15:01:42 +05:30
Anand Baburajan
4ff70db668 Merge branch 'develop' into asset_depreciation_schedule 2022-12-27 14:59:53 +05:30
Deepesh Garg
8263bf9a9a fix: Random behaviour while picking items using picklist (#33449) 2022-12-27 14:59:35 +05:30
anandbaburajan
482116db9f chore: improve tests 2022-12-27 10:03:32 +05:30
Anand Baburajan
6f4e6fafa9 Merge branch 'develop' into asset_depreciation_schedule 2022-12-27 07:36:32 +05:30
anandbaburajan
6d791cabd1 chore: more refactoring 2022-12-26 22:13:11 +05:30
Sagar Sharma
4e2291f52d Merge pull request #33437 from s-aga-r/fix/purchase-order/shipping_address
fix: `shipping_address` in PO for non-drop ship item
2022-12-26 21:20:40 +05:30
Sagar Sharma
88edc412e3 Merge branch 'develop' into fix/purchase-order/shipping_address 2022-12-26 12:00:39 +05:30
s-aga-r
67a7ccf3ce fix: shipping_address for non-drop shipping item 2022-12-26 11:57:50 +05:30
Deepesh Garg
8a79efab4b feat: Accounting Dimension updation in Payment Request and Entry (#33411) 2022-12-26 10:17:55 +05:30
Solufyin
7d9f3f23dd fix: Customer Primary Contact (#33424)
Co-authored-by: Nihantra C. Patel <n.patel.serpentcs@gmail.com>
2022-12-26 10:15:10 +05:30
Sagar Sharma
9858d9d968 Merge pull request #33434 from s-aga-r/fix/github-issue/32258
fix(ux): `shipping_address` in PO
2022-12-25 19:40:09 +05:30
Sagar Sharma
32f3b64a89 Merge branch 'develop' into fix/github-issue/32258 2022-12-25 18:12:08 +05:30
s-aga-r
7e1b6b3c2a fix: shipping_address in PO 2022-12-25 18:11:05 +05:30
anandbaburajan
03662be150 chore: have different functions for draft. active and cancelled depr schedules 2022-12-25 18:05:19 +05:30
ruthra kumar
a31e9d3afe Merge pull request #33402 from ruthra-kumar/hidden_party_detail_fields_for_better_handling_of_permission
refactor: Customer and Supplier Ledger summary will have hidden fields for better handling of user permission
2022-12-25 16:25:13 +05:30
ruthra kumar
a0484793c3 refactor: remove unrelated filters from Supplier Ledger Summary
Territory, Sales Partner and Sales Person doesn't belong in Supplier Ledger
2022-12-24 11:20:39 +05:30
ruthra kumar
89229d9b58 refactor: additional doctype access for 'Accounts User' role 2022-12-24 11:20:16 +05:30
ruthra kumar
bfa511cb65 refactor: hidden columns to help framework handle user permissions
'territory', 'supplier_group', 'customer_group' have been added as
hidden columns to handle 'user permission' based access control.
2022-12-24 10:30:30 +05:30
rohitwaghchaure
40769998c6 Merge pull request #33422 from rohitwaghchaure/fix-stock-entry-submit-performance
fix: timeout error while submitting stock entry
2022-12-23 13:57:25 +05:30
Rohit Waghchaure
a05c47e499 fix: timeout error while submitting stock entry
Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-12-23 13:27:32 +05:30
Anand Baburajan
b17ef34042 Merge branch 'develop' into asset_depreciation_schedule 2022-12-23 11:02:17 +05:30
anandbaburajan
3e91a56c19 chore: only consider draft and active assets in patch, and allow asset depr schedule to be manually createed 2022-12-23 11:01:18 +05:30
ruthra kumar
8f5d8e0474 Merge pull request #33418 from ruthra-kumar/filter_issue_in_ar_ap_report
fix: payment terms and sales partner filter issue in Accounts Receivable report
2022-12-22 11:38:38 +05:30
ruthra kumar
13c4420f42 fix: payment terms and sales partner filter issue in AR/AP report 2022-12-22 10:55:22 +05:30
ruthra kumar
a26698b88e Merge pull request #33410 from ruthra-kumar/typeerror_on_gp_due_to_incorrect_warehouse_on_bundle_item
fix: TypeError on GP Report due to multiple warehouse on bundled items
2022-12-21 18:26:40 +05:30
ruthra kumar
5918bb03f7 test: type error on bundled products with different warehouses 2022-12-21 17:47:57 +05:30
ruthra kumar
e684eb32d0 fix: typerror on multi warehouse in Packed Items
DN(with bundled item with varying warehouses)-> Sales Invoice.
2022-12-21 15:09:55 +05:30
sonali
81e5f71172 fix: json issue 2022-12-21 14:02:54 +05:30
sonali
6b5276398e fix: linters 2022-12-21 13:32:16 +05:30
sonali
645869e6ff feat: added arguments of posting date and reference date 2022-12-21 12:58:30 +05:30
Deepesh Garg
76be35aaea Merge pull request #33406 from deepeshgarg007/cs_cf_report_fix
fix: Consolidated financial report
2022-12-20 18:22:58 +05:30
Deepesh Garg
ade83cbab3 fix: Consolidated financial report 2022-12-20 16:45:46 +05:30
Deepesh Garg
1da14b7ec3 Merge pull request #33393 from deepeshgarg007/cc_filter_cashflow_report
fix: Cost center filter not working in cash flow report
2022-12-20 13:46:18 +05:30
Deepesh Garg
925387550e Merge pull request #33350 from deepeshgarg007/payment_request_flow
fix: Payment Request flow fixes from Order to Payment Entry
2022-12-20 13:45:15 +05:30
Deepesh Garg
9dc1509cf5 Merge pull request #33358 from resilient-tech/fix-appointment-booking
fix: remove unnecessary permissions from Appointment and Appointment Booking Settings
2022-12-20 11:53:01 +05:30
Deepesh Garg
31c95deb88 chore: More fixes 2022-12-20 11:45:51 +05:30
Deepesh Garg
ff48634cbb Merge branch 'develop' of https://github.com/frappe/erpnext into payment_request_flow 2022-12-20 11:42:15 +05:30
Deepesh Garg
e25b98b620 chore: Update test case 2022-12-20 11:42:05 +05:30
Deepesh Garg
068df9f815 chore: remove print statement 2022-12-20 10:00:53 +05:30
Deepesh Garg
d0dbfec052 fix: Cost center filter not working in cash flow report 2022-12-20 09:59:27 +05:30
rohitwaghchaure
1ed2230e4c Merge pull request #33382 from rohitwaghchaure/fixed-pick-list-issue
fix: unsupported operand type(s) for +=: 'int' and 'NoneType'
2022-12-20 09:47:29 +05:30
rohitwaghchaure
eaa04abe29 Merge pull request #33387 from rohitwaghchaure/audit-to-fix-incorrect-valuation-entry
fix: daily scheduler to identify and fix stock transfer entries having incorrect valuation
2022-12-20 09:46:57 +05:30
Rohit Waghchaure
f31612376a test: added test case to validate audit for incorrect entries 2022-12-20 00:14:41 +05:30
Rohit Waghchaure
b1721b79ce fix: daily scheduler to identify and fix stock transfer entries having incorrect valuation 2022-12-19 23:33:44 +05:30
rohitwaghchaure
7851adb49a Merge branch 'develop' into fixed-pick-list-issue 2022-12-19 23:32:06 +05:30
Ankush Menat
88ce11f03d fix: incorrect type hints (#33381)
[skip ci]
2022-12-19 16:44:19 +05:30
Rohit Waghchaure
2b4eae5f84 fix: unsupported operand type(s) for +=: 'int' and 'NoneType' 2022-12-19 16:24:55 +05:30
ruthra kumar
65db9cea25 Merge pull request #33380 from ruthra-kumar/err_for_invoices_should_reflect_in_ar_ap_report
fix: ERR journals should reported in AR/AP
2022-12-18 16:56:19 +05:30
ruthra kumar
2ed86760d7 test: err for party should be in AR/AP report 2022-12-18 12:40:07 +05:30
ruthra kumar
b09eade3e4 fix: ERR journals reported in AR/AP
Exchange Rate Revaluation on Receivable/Payable will included in AR/AP report
2022-12-18 06:38:23 +05:30
Gokulnath
4ecce242a8 feat: adding warehouse filter for sales order ananlysis report
feat: adding warehouse filter for sales order ananlysis report
2022-12-17 20:06:01 +05:30
Deepesh Garg
67c5cec505 Merge pull request #33339 from barredterra/print-rfq
feat: more control when printing RFQ
2022-12-17 19:24:57 +05:30
Deepesh Garg
6238fd9d9e Merge pull request #33341 from deepeshgarg007/tds_tcs_cost_center
fix: Cost Center for tax withholding invoices
2022-12-17 19:24:34 +05:30
sonali
05b6fce03d feat:filters on bank reconciliation
Added date filters on bank transactions, payment entries and journal entries and sorted list as per date in ascending order.
2022-12-17 17:15:28 +05:30
Deepesh Garg
2a4eec245a Merge pull request #33371 from deepeshgarg007/coa_import_srbnb
fix: Unable to import COA through importer
2022-12-17 16:42:37 +05:30
Deepesh Garg
3b66920342 fix: Unable to import COA through importer 2022-12-16 19:22:29 +05:30
Deepesh Garg
0e86cde64b Merge branch 'develop' into print-rfq 2022-12-16 16:24:02 +05:30
Sagar Vora
9989ccbb02 Merge branch 'develop' into fix-appointment-booking 2022-12-16 10:36:48 +00:00
Daizy Modi
4802d719ed fix: removed unused data and minor changes 2022-12-16 15:55:58 +05:30
Deepesh Garg
6bb22c703a Merge pull request #33275 from pps190/fix-pe-exchange-rate-precision
fix: use highest precision for exchange rate.
2022-12-16 15:43:36 +05:30
Deepesh Garg
50421b3d7d Merge pull request #33315 from kunhimohamed/develop
fix: at create_customer_or_supplier on session creation
2022-12-16 15:04:10 +05:30
Deepesh Garg
b76129c1dd Merge pull request #33286 from artykbasar/develop
Subscription Cost center value is fixed to Default value(Bug fix)
2022-12-16 14:44:51 +05:30
Deepesh Garg
5c50a46822 Merge pull request #33362 from deepeshgarg007/exclude_gst_credential_doctype
feat: Ignore company related doctype for other apps via hooks
2022-12-16 11:07:47 +05:30
Daizy Modi
5d0b5c8d2a fix: pass necessary params instead of args 2022-12-16 10:10:29 +05:30
Deepesh Garg
1a40c04b72 feat: Ignore company related doctype for other apps via hooks 2022-12-15 18:51:58 +05:30
sonali
408c89df03 Feat:Filter on Payment Entries and Journal Entries
Applying filters on Payement entries and Journal Entries as per reference  date and posting date
2022-12-15 18:09:57 +05:30
rohitwaghchaure
da1d8da355 Merge pull request #33355 from rohitwaghchaure/fixed-do-not-show-disabled-items
fix: disabled items showing in the report Itemwise Recommended Reorder Level
2022-12-15 18:08:05 +05:30
Daizy Modi
56f3ac15d8 fix: removed unncessary changes 2022-12-15 18:02:14 +05:30
Daizy Modi
4bfe2ea572 fix: agent assignment and permissions for appointment 2022-12-15 17:19:28 +05:30
rohitwaghchaure
5cbbb5d59e Merge pull request #33354 from rohitwaghchaure/fixed-trivial-discount-amount
fix: unsupported operand type(s) for +: 'int' and 'NoneType'
2022-12-15 17:13:46 +05:30
Rohit Waghchaure
ae31ff1c48 fix: disabled items showing in the report 'Itemwise Recommended Reorder Level
'
2022-12-15 17:05:53 +05:30
Daizy Modi
ac51c27500 fix: fetch required details from appointment booking settings 2022-12-15 16:53:51 +05:30
Daizy Modi
9a00b3bdbd fix: format html of verify email for book appointment 2022-12-15 16:51:00 +05:30
Daizy Modi
25f0b26a17 fix: remove unused page book-appointment 2022-12-15 16:49:23 +05:30
Daizy Modi
ae8dd2b2bc fix: remove guest role from doctype 2022-12-15 16:47:27 +05:30
Rohit Waghchaure
0f28074e5a fix: unsupported operand type(s) for +: 'int' and 'NoneType' 2022-12-15 16:36:47 +05:30
ruthra kumar
d126c8030f Merge pull request #33335 from ruthra-kumar/cost_center_issue_on_reconciliation_tool
fix: paid invoices shows up as outstanding when 'cost_center' filter is applied
2022-12-15 15:02:18 +05:30
Anand Baburajan
246d3b4075 Merge branch 'develop' into asset_depreciation_schedule 2022-12-15 14:51:16 +05:30
anandbaburajan
a358f77774 chore: move patch to post_model_sync and cancel asset depr schedule properly 2022-12-15 14:50:53 +05:30
ruthra kumar
a998a8a2da test: cost center should not affect outstanding calculation 2022-12-15 14:28:33 +05:30
Deepesh Garg
dc178984ae fix: Payment Request flow fixes from Order to Payment Entry 2022-12-15 14:15:20 +05:30
anandbaburajan
7f5e761c04 chore: add patch 2022-12-15 13:13:04 +05:30
Deepesh Garg
3a8a467edb Merge pull request #33329 from Gokulnath17/Gokulnath_dev
fix: in gross profit report
2022-12-15 12:01:39 +05:30
Deepesh Garg
076527bb88 Merge pull request #33305 from barredterra/incoterm-named-place
feat: incoterm named place
2022-12-15 11:59:54 +05:30
Gokulnath
f73976946e Merge branch 'develop' into Gokulnath_dev 2022-12-15 10:22:49 +05:30
Deepesh Garg
b7e9942681 Merge pull request #33309 from barredterra/refactor-validate_payment_against_negative_invoice
refactor: translatable strings and guard clause
2022-12-15 09:21:16 +05:30
rohitwaghchaure
9bf2682218 Merge pull request #33323 from barredterra/translate-overbilling-overdelivery
fix: translatability of warning on overbilling/-receipt/-delivery
2022-12-14 23:24:11 +05:30
Deepesh Garg
26277cfcf3 chore: resolve errors in test 2022-12-14 21:22:48 +05:30
Deepesh Garg
973ef33eb5 fix: Cost Center for tax withholding invoices 2022-12-14 20:41:00 +05:30
barredterra
8717148d9b feat: improve visibility of default values 2022-12-14 14:14:29 +01:00
barredterra
ce9626fead feat: more control when printing RFQ 2022-12-14 14:03:36 +01:00
Gokulnath
d404a03947 Merge branch 'develop' into Gokulnath_dev 2022-12-14 17:38:16 +05:30
ruthra kumar
8eb93004f7 fix: cost_center filter fix for 'Get Outstanding Invoice' in PE 2022-12-14 16:16:22 +05:30
rohitwaghchaure
21c86bd649 Merge pull request #33332 from rohitwaghchaure/fixed--missing-required-argument
fix: get_serial_nos_for_fg() missing 1 required positional argument: …
2022-12-14 16:06:58 +05:30
ruthra kumar
6d9d730759 fix: cost_center filter gives incorrect output
filtering on cost center gives invoices that are reconciled as having outstanding
2022-12-14 16:05:15 +05:30
Rohit Waghchaure
410a58b3de fix: get_serial_nos_for_fg() missing 1 required positional argument: 'args' 2022-12-14 15:33:36 +05:30
anandbaburajan
c99cd74a15 chore: handle some error cases and add empty patch file 2022-12-14 13:20:37 +05:30
Gokulnath17
41fc3be339 fixes in gross profit report 2022-12-14 10:46:11 +05:30
barredterra
36997d9788 fix: translation for warning on Overbilling/-receipt/-delivery 2022-12-13 18:59:20 +01:00
Anand Baburajan
8534390627 Merge branch 'develop' into asset_depreciation_schedule 2022-12-13 20:49:06 +05:30
anandbaburajan
22ef342ac7 chore: fixing all tests 2022-12-13 20:48:34 +05:30
anandbaburajan
df134c7c5b chore: fixing some tests 2022-12-13 16:26:33 +05:30
Nabin Hait
5ea6080a6e Merge pull request #33300 from ssiyad/fix/pos/var_typo
fix(pos): variable typo: `s_pos` -> `is_pos`
2022-12-13 15:21:10 +05:30
Nabin Hait
c5d21b2461 Merge pull request #33314 from s-aga-r/fix/github-issue/33145
fix: `Enough Parts to Build` in `BOM Stock Report`
2022-12-13 15:19:40 +05:30
ruthra kumar
3db446e35a Merge pull request #33313 from nabinhait/tax_detail_report_perm_issue
fix: Permission issue in Tax Detail report
2022-12-13 14:27:08 +05:30
kunhi
15e3b7f218 fix: at create_customer_or_supplier on session creation 2022-12-13 12:41:56 +04:00
Sagar Sharma
f9be137cf5 Merge branch 'develop' into fix/github-issue/33145 2022-12-13 14:00:51 +05:30
s-aga-r
723c64ba73 fix: Enough Parts to Build in BOM Stock Report 2022-12-13 14:00:30 +05:30
Nabin Hait
aa787e4030 fix: Permission issue in Tax Detail report 2022-12-13 13:16:24 +05:30
ruthra kumar
2175784142 Merge pull request #33303 from ruthra-kumar/incorrect_balance_on_consolidate_balance_sheet
fix: incorrect balance on parent company on consolidate Balance sheet due to key mismatch
2022-12-13 09:04:13 +05:30
barredterra
f20370c5ef refactor: translatable strings and guard clause 2022-12-13 02:36:12 +01:00
Sagar Sharma
cb49055aac Merge pull request #33304 from s-aga-r/fix/so-mr-ref
fix: `Material Request` reference in internal `Sales Order`
2022-12-12 23:48:14 +05:30
barredterra
e057e1dfe7 feat: incoterm named place 2022-12-12 18:49:47 +01:00
s-aga-r
78b438f6cf fix: Material Request reference in internal Sales Order 2022-12-12 22:41:44 +05:30
ruthra kumar
7b3316dc31 fix: incorrect balance on parent company due to key mismatch 2022-12-12 20:15:59 +05:30
rohitwaghchaure
5c0f8ee44f Merge pull request #33281 from tundebabzy/29976
fix: maintain same rate throughout sales cycle doesn't work with quotation
2022-12-12 19:30:50 +05:30
Sabu Siyad
7d64bf78cf fix(pos): variable typo: s_pos -> is_pos
Signed-off-by: Sabu Siyad <hello@ssiyad.com>
2022-12-12 19:09:00 +05:30
anandbaburajan
28d4942d6c chore: fix validation and add make_schedules_editable 2022-12-12 18:19:34 +05:30
anandbaburajan
1ea2ba0dea chore: handle some cases where asset_depr_schedule doesn't exist 2022-12-12 17:31:57 +05:30
anandbaburajan
b997d1eb87 chore: add some validation, shorten some function names 2022-12-12 17:25:38 +05:30
Anand Baburajan
f8cd424559 Merge branch 'develop' into asset_depreciation_schedule 2022-12-12 16:36:59 +05:30
anandbaburajan
ec6505d747 chore: fix some bugs, refactor some functions, add proper notes 2022-12-12 16:35:30 +05:30
Ankush Menat
915e0347b0 chore!: remove activity log feeds (#33294)
- This contains little to no information and practically no one uses this.
- Also causes a lot of problem by adding way too many feeds in activity
  log to the point where activity page doesn't even load.
2022-12-12 15:14:30 +05:30
Ankush Menat
593626f502 perf: add indexes on payment entry reference (#33288)
Adds index on:
1. reference doctype
2. reference name

*Why not composite index?*

There are three type of queries on this doctype

- filtering ref_doctype - doctype index helps here
- filtering ref_name - name index helps here
- filtering both - name index helps here too. Since it has sufficiently
  high cardinality. Composite index wont help in case where ref_doctype
  isn't specfied.


[skip ci]
2022-12-12 12:58:11 +05:30
artykbasar
d512919f5c Subscription Cost center value is fixed to Default value(Bug fix)
self.cost_center 
    field value keeps changing to 
erpnext.get_default_cost_center(self.get("company"))
    after validation of this doctype. This overrides the user input.
simple fix, it will first check if the field is empty, if empty then puts the company's default cost center value if not then user input will be saved.
2022-12-11 08:51:34 +00:00
Tunde Akinyanmi
71aa8c5e1c test: refactor test case 2022-12-09 14:33:54 +01:00
Tunde Akinyanmi
d193a14b8f test: ensure test case sets Selling Settings 2022-12-09 14:09:54 +01:00
anandbaburajan
90e1b9cb3d chore: fix asset depr schedule notes 2022-12-09 16:18:40 +05:30
Tunde Akinyanmi
97ddfcfc7c fix: Maintain Same Rate Throughout Sales Cycle doesn't work
Issue #29976 was partly fixed by #32923 but the problem still persists.
The reason is because an incorrect fieldname was passed to the
`validate_rate_with_reference_doc` method.
This commit fixes it
2022-12-09 10:29:28 +01:00
anandbaburajan
16365bfca3 chore: more refactoring 2022-12-09 14:04:00 +05:30
Devin Slauenwhite
2010b1b6e8 fix: use highest precision for exchange rate. 2022-12-08 16:26:07 -05:00
anandbaburajan
77dc8e7966 fix: bug in posting depr entries 2022-12-09 00:58:19 +05:30
anandbaburajan
187e1a324a chore: refactor get_depreciable_assets 2022-12-09 00:46:56 +05:30
anandbaburajan
1fd73af744 chore: refactor some reports 2022-12-09 00:28:34 +05:30
Deepesh Garg
7d41f63c5d Merge pull request #33200 from deepeshgarg007/buying_selling_pricing_rule
fix: Buying and selling check in pricing rule
2022-12-08 18:41:42 +05:30
Deepesh Garg
6db52930d8 Merge branch 'develop' of https://github.com/frappe/erpnext into buying_selling_pricing_rule 2022-12-08 18:05:05 +05:30
Deepesh Garg
6192af5cf0 chore: Update tests 2022-12-08 18:04:40 +05:30
sonali
8e7c8a6482 Update bank_reconciliation_tool.json
Adding fields in bank reconciliation tool
2022-12-08 17:23:08 +05:30
Deepesh Garg
b179514273 Merge pull request #33269 from ssiyad/fix/ecommerce/breadcrumb_base
fix(ecommerce): remove query parameters from referrer
2022-12-08 17:11:34 +05:30
Sabu Siyad
b6bd408f19 fix(ecommerce): remove query parameters from referer
inclusion of query parameters results in logic failure

example:
- logic check if referrer is `all-products`
- `http://shop.example/all-products` -> `all-products`, valid outcome
- `http://shop.example/all-products?start=1` -> `all-products?start=1`,
  invalid outcome

Signed-off-by: Sabu Siyad <hello@ssiyad.com>
2022-12-08 16:47:50 +05:30
Ankush Menat
0b86b1baca refactor: make payments app a soft dependency (#33245)
refactor: make payment app a soft dependency
2022-12-08 16:40:13 +05:30
sonali
447272aa4d Filters on Bank Reconciliation
Applying date filter on transactions and all the bank entries and also gives the filter the bank entries as per reference date. Sorted all transactions and entries as per date in ascending order. Also added posting date columns in all bank entries and default checkbox tick of journal entry, hide the sales invoice and purchase invoice checkbox.
2022-12-08 16:11:53 +05:30
Deepesh Garg
07c815f35f Merge pull request #33253 from niyazrazak/patch-9
feat: get lead with WhatsApp number
2022-12-08 15:19:13 +05:30
Deepesh Garg
81397ba3ee Merge pull request #33227 from barredterra/add-translation-variable-order
fix: add translation variable index
2022-12-08 15:17:07 +05:30
Deepesh Garg
f0487451f7 Merge pull request #33248 from QwQuan/develop
fix: bugs in zh.csv
2022-12-08 15:16:16 +05:30
sonali
e5a1189bec Update bank_reconciliation_tool.py
Applying date filter on transactions and all the bank entries and also gives the filter the bank entries as per reference date. Sorted all transactions and entries as per date in ascending order.
Also added posting date columns in all bank entries and default checkbox tick of journal entry, hide the sales invoice and purchase invoice checkbox.
2022-12-08 13:29:28 +05:30
ruthra kumar
1d37c0143f Merge pull request #33254 from ruthra-kumar/index_error_on_customer_master
fix: index error on customer master
2022-12-08 12:52:20 +05:30
rohitwaghchaure
e451639ff6 Merge pull request #33258 from rohitwaghchaure/fixed-total-value-in-report
fix: total value in Warehouse Wise Stock Balance
2022-12-08 10:13:03 +05:30
Rohit Waghchaure
f598da7c81 fix: total value in Warehouse Wise Stock Balance 2022-12-08 00:55:45 +05:30
rohitwaghchaure
5e0f4eb580 Merge pull request #33255 from s-aga-r/fix/github-issue/33212
fix: order status in `Production Planning Report`
2022-12-07 23:36:12 +05:30
s-aga-r
632c08f7e0 fix: order status in Production Planning Report 2022-12-07 22:47:06 +05:30
ruthra kumar
cf1e3dc8ea fix: index error on customer master 2022-12-07 20:48:40 +05:30
MOHAMMED NIYAS
922375c3ba feat: get lead with WhatsApp number 2022-12-07 17:50:35 +05:30
wuzhouquan
a6fe79f29d fix: bugs in zh.csv 2022-12-07 15:04:56 +08:00
anandbaburajan
18fc2b5695 chore: fix bug in unlink_asset_reference 2022-12-06 23:34:56 +05:30
anandbaburajan
2cd42dbb10 chore: refactor get_finance_book_value_map 2022-12-06 23:16:02 +05:30
anandbaburajan
e7d404a30a chore: remove finance_book and finance_book_id from depreciation_schedule and refactor some functions 2022-12-06 21:33:20 +05:30
anandbaburajan
8365d6bdb7 fix: refactor reverse_depreciation_entry_made_after_disposal and fix fb bug 2022-12-06 17:58:38 +05:30
barredterra
748c74ba52 fix: add translation variable order 2022-12-05 18:24:22 +01:00
Deepesh Garg
0581000990 fix: Remove free items 2022-12-05 17:59:02 +05:30
Deepesh Garg
55c0770280 Merge branch 'develop' of https://github.com/frappe/erpnext into buying_selling_pricing_rule 2022-12-05 15:43:29 +05:30
Deepesh Garg
5f821b93a5 chore: Add POS Invoices 2022-12-05 15:43:03 +05:30
anandbaburajan
83ed93fbb6 chore: refactor chart and manual set_accumulated_depreciation logic 2022-12-04 22:45:48 +05:30
anandbaburajan
ca8c827492 chore: refactor schedules in split_asset functions 2022-12-04 19:22:58 +05:30
Deepesh Garg
b741ae143c fix: Reapply pricing rule on qty change 2022-12-02 17:14:06 +05:30
Deepesh Garg
f54838ab56 fix: Buying and selling check in pricing rule 2022-12-01 21:23:17 +05:30
anandbaburajan
f20238fa3e chore: use make_new_active_asset_depr_schedules_and_cancel_current_ones instead of prepare_depreciation_data 2022-12-01 15:15:32 +05:30
anandbaburajan
96ede2fcf9 fix: bug in new depr schedule 2022-11-29 21:30:23 +05:30
anandbaburajan
7d09440579 chore: more refactoring 2022-11-25 16:49:44 +05:30
anandbaburajan
4e63ba3ac6 chore: refactor schedules in journal_entry 2022-11-24 17:39:11 +05:30
anandbaburajan
de17367a36 chore: finish refactoring asset_value_adjustment 2022-11-24 16:16:36 +05:30
anandbaburajan
f35b19eac3 chore: renaming functions and variables again, and continuing refactoring AssetValueAdjustment 2022-11-24 15:33:21 +05:30
anandbaburajan
7db66b0916 chore: renaming some functions and variables, and partially refactoring AssetValueAdjustment 2022-11-24 13:02:48 +05:30
anandbaburajan
76f28de7eb chore: refactor more functions to use new depr schedule 2022-11-23 18:04:54 +05:30
Anand Baburajan
a66d9f8e8e Merge branch 'develop' into asset_depreciation_schedule 2022-11-17 20:17:21 +05:30
anandbaburajan
417180e6ba chore: refactor some functions to use new depr schedule 2022-11-14 17:51:11 +05:30
anandbaburajan
ffd41703de chore: add expected_value_after_useful_life in depr schedule 2022-11-14 14:36:10 +05:30
anandbaburajan
ca3581d055 chore: rename modify_draft_asset_depreciation_schedules 2022-11-14 12:47:48 +05:30
anandbaburajan
ed495dc846 chore: add convert_draft_asset_depreciation_schedules_into_active and fix some bugs 2022-11-14 12:45:49 +05:30
anandbaburajan
97ab7bd36b chore: remove some unwanted functions in asset 2022-11-11 16:27:29 +05:30
anandbaburajan
710d2452b7 feat: moving, refactoring and adding functions to asset_depreciation_schedule 2022-11-11 16:20:17 +05:30
anandbaburajan
5a274176d3 feat: add asset_depreciation_schedule 2022-11-01 11:45:17 +05:30
Devin Slauenwhite
ef6480803b chore: linter 2022-06-22 14:10:40 -04:00
Devin Slauenwhite
199b8dd0e3 Merge branch 'develop' into fix-reserve-qty 2022-06-22 14:06:35 -04:00
Devin Slauenwhite
6a6c560375 fix: move to transcation settings 2022-06-17 15:51:11 -04:00
Devin Slauenwhite
179e2d2c74 fix: reset selling setting 2022-06-17 15:29:32 -04:00
Devin Slauenwhite
591b5917a9 fix: re-assign after append query 2022-06-17 15:27:17 -04:00
Devin Slauenwhite
0328874018 fix: syntax missing ) 2022-06-17 14:45:33 -04:00
Devin Slauenwhite
7855a59843 Merge branch 'develop' into fix-reserve-qty 2022-06-17 14:39:31 -04:00
Devin Slauenwhite
494bbf0124 feat: add checkbox to reserve qty on sales return 2022-06-17 13:51:33 -04:00
Devin Slauenwhite
f3f26d2c78 refactor: get_reserved_qty query builder 2022-06-17 11:51:21 -04:00
Devin Slauenwhite
d259c2e36a fix: merge conflict 2022-06-17 11:50:54 -04:00
Devin Slauenwhite
f39422afd8 Merge branch 'develop' into fix-reserve-qty
# Conflicts:
#	erpnext/patches.txt
#	erpnext/public/js/utils/barcode_scanner.js
#	erpnext/regional/report/gstr_1/gstr_1.py
#	erpnext/stock/doctype/delivery_note/test_delivery_note.py
2022-06-17 08:04:52 -04:00
Devin Slauenwhite
5a402a5709 fix(test): use unique item in sales order. 2022-05-17 13:32:26 -04:00
Devin Slauenwhite
4d0fa85a75 fix(test): update_prevdoc_status 2022-05-16 19:45:59 -04:00
Devin Slauenwhite
47f867b77a test: don't reserve qty on sales return. 2022-05-16 14:27:45 -04:00
Devin Slauenwhite
1d1c975da1 Merge remote-tracking branch 'upstream/develop' into fix-reserve-qty 2022-05-16 11:10:28 -04:00
Devin Slauenwhite
695e2bcfbc fix: don't reserve qty on sales return. 2022-05-14 11:06:24 -04:00
791 changed files with 54379 additions and 38360 deletions

View File

@@ -66,7 +66,8 @@ ignore =
F841,
E713,
E712,
B023
B023,
B028
max-line-length = 200

View File

@@ -3,52 +3,71 @@ import requests
from urllib.parse import urlparse
docs_repos = [
"frappe_docs",
"erpnext_documentation",
WEBSITE_REPOS = [
"erpnext_com",
"frappe_io",
]
DOCUMENTATION_DOMAINS = [
"docs.erpnext.com",
"frappeframework.com",
]
def uri_validator(x):
result = urlparse(x)
return all([result.scheme, result.netloc, result.path])
def docs_link_exists(body):
for line in body.splitlines():
for word in line.split():
if word.startswith('http') and uri_validator(word):
parsed_url = urlparse(word)
if parsed_url.netloc == "github.com":
parts = parsed_url.path.split('/')
if len(parts) == 5 and parts[1] == "frappe" and parts[2] in docs_repos:
return True
elif parsed_url.netloc == "docs.erpnext.com":
return True
def is_valid_url(url: str) -> bool:
parts = urlparse(url)
return all((parts.scheme, parts.netloc, parts.path))
def is_documentation_link(word: str) -> bool:
if not word.startswith("http") or not is_valid_url(word):
return False
parsed_url = urlparse(word)
if parsed_url.netloc in DOCUMENTATION_DOMAINS:
return True
if parsed_url.netloc == "github.com":
parts = parsed_url.path.split("/")
if len(parts) == 5 and parts[1] == "frappe" and parts[2] in WEBSITE_REPOS:
return True
return False
def contains_documentation_link(body: str) -> bool:
return any(
is_documentation_link(word)
for line in body.splitlines()
for word in line.split()
)
def check_pull_request(number: str) -> "tuple[int, str]":
response = requests.get(f"https://api.github.com/repos/frappe/erpnext/pulls/{number}")
if not response.ok:
return 1, "Pull Request Not Found! ⚠️"
payload = response.json()
title = (payload.get("title") or "").lower().strip()
head_sha = (payload.get("head") or {}).get("sha")
body = (payload.get("body") or "").lower()
if (
not title.startswith("feat")
or not head_sha
or "no-docs" in body
or "backport" in body
):
return 0, "Skipping documentation checks... 🏃"
if contains_documentation_link(body):
return 0, "Documentation Link Found. You're Awesome! 🎉"
return 1, "Documentation Link Not Found! ⚠️"
if __name__ == "__main__":
pr = sys.argv[1]
response = requests.get("https://api.github.com/repos/frappe/erpnext/pulls/{}".format(pr))
if response.ok:
payload = response.json()
title = (payload.get("title") or "").lower().strip()
head_sha = (payload.get("head") or {}).get("sha")
body = (payload.get("body") or "").lower()
if (title.startswith("feat")
and head_sha
and "no-docs" not in body
and "backport" not in body
):
if docs_link_exists(body):
print("Documentation Link Found. You're Awesome! 🎉")
else:
print("Documentation Link Not Found! ⚠️")
sys.exit(1)
else:
print("Skipping documentation checks... 🏃")
exit_code, message = check_pull_request(sys.argv[1])
print(message)
sys.exit(exit_code)

View File

@@ -8,8 +8,9 @@ sudo apt update && sudo apt install redis-server libcups2-dev
pip install frappe-bench
githubbranch=${GITHUB_BASE_REF:-${GITHUB_REF##*/}}
frappeuser=${FRAPPE_USER:-"frappe"}
frappebranch=${FRAPPE_BRANCH:-${GITHUB_BASE_REF:-${GITHUB_REF##*/}}}
frappebranch=${FRAPPE_BRANCH:-$githubbranch}
git clone "https://github.com/${frappeuser}/frappe" --branch "${frappebranch}" --depth 1
bench init --skip-assets --frappe-path ~/frappe --python "$(which python)" frappe-bench
@@ -41,12 +42,17 @@ fi
install_whktml() {
wget -O /tmp/wkhtmltox.tar.xz https://github.com/frappe/wkhtmltopdf/raw/master/wkhtmltox-0.12.3_linux-generic-amd64.tar.xz
tar -xf /tmp/wkhtmltox.tar.xz -C /tmp
sudo mv /tmp/wkhtmltox/bin/wkhtmltopdf /usr/local/bin/wkhtmltopdf
sudo chmod o+x /usr/local/bin/wkhtmltopdf
if [ "$(lsb_release -rs)" = "22.04" ]; then
wget -O /tmp/wkhtmltox.deb https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox_0.12.6.1-2.jammy_amd64.deb
sudo apt install /tmp/wkhtmltox.deb
else
echo "Please update this script to support wkhtmltopdf for $(lsb_release -ds)"
exit 1
fi
}
install_whktml &
wkpid=$!
cd ~/frappe-bench || exit
@@ -55,11 +61,13 @@ sed -i 's/schedule:/# schedule:/g' Procfile
sed -i 's/socketio:/# socketio:/g' Procfile
sed -i 's/redis_socketio:/# redis_socketio:/g' Procfile
bench get-app payments
bench get-app payments --branch ${githubbranch%"-hotfix"}
bench get-app erpnext "${GITHUB_WORKSPACE}"
if [ "$TYPE" == "server" ]; then bench setup requirements --dev; fi
wait $wkpid
bench start &> bench_run_logs.txt &
CI=Yes bench build --app frappe &
bench --site test_site reinstall --yes

View File

@@ -11,6 +11,6 @@
"root_login": "root",
"root_password": "root",
"host_name": "http://test_site:8000",
"install_apps": ["erpnext"],
"install_apps": ["payments", "erpnext"],
"throttle_user_limit": 100
}

View File

@@ -13,10 +13,10 @@ jobs:
with:
fetch-depth: 0
persist-credentials: false
- name: Setup Node.js v14
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: 14
node-version: 18
- name: Setup dependencies
run: |
npm install @semantic-release/git @semantic-release/exec --no-save
@@ -28,4 +28,4 @@ jobs:
GIT_AUTHOR_EMAIL: "developers@frappe.io"
GIT_COMMITTER_NAME: "Frappe PR Bot"
GIT_COMMITTER_EMAIL: "developers@frappe.io"
run: npx semantic-release
run: npx semantic-release

View File

@@ -7,7 +7,6 @@ on:
- '**.css'
- '**.md'
- '**.html'
- '**.csv'
push:
branches: [ develop ]
paths-ignore:
@@ -16,12 +15,12 @@ on:
workflow_dispatch:
inputs:
user:
description: 'user'
description: 'Frappe Framework repository user (add your username for forks)'
required: true
default: 'frappe'
type: string
branch:
description: 'Branch name'
description: 'Frappe Framework branch'
default: 'develop'
required: false
type: string

View File

@@ -32,8 +32,8 @@ repos:
- id: black
additional_dependencies: ['click==8.0.4']
- repo: https://github.com/timothycrosley/isort
rev: 5.9.1
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort
exclude: ".*setup.py$"

View File

@@ -3,26 +3,23 @@
# These owners will be the default owners for everything in
# the repo. Unless a later match takes precedence,
erpnext/accounts/ @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
erpnext/assets/ @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
erpnext/loan_management/ @nextchamp-saqib @deepeshgarg007
erpnext/regional @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
erpnext/selling @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
erpnext/support/ @nextchamp-saqib @deepeshgarg007
pos* @nextchamp-saqib
erpnext/accounts/ @deepeshgarg007 @ruthra-kumar
erpnext/assets/ @anandbaburajan @deepeshgarg007
erpnext/loan_management/ @deepeshgarg007
erpnext/regional @deepeshgarg007 @ruthra-kumar
erpnext/selling @deepeshgarg007 @ruthra-kumar
erpnext/support/ @deepeshgarg007
pos*
erpnext/buying/ @rohitwaghchaure @s-aga-r
erpnext/maintenance/ @rohitwaghchaure @s-aga-r
erpnext/manufacturing/ @rohitwaghchaure @s-aga-r
erpnext/quality_management/ @rohitwaghchaure @s-aga-r
erpnext/stock/ @rohitwaghchaure @s-aga-r
erpnext/subcontracting @rohitwaghchaure @s-aga-r
erpnext/crm/ @NagariaHussain
erpnext/education/ @rutwikhdev
erpnext/projects/ @ruchamahabal
erpnext/controllers/ @deepeshgarg007 @rohitwaghchaure
erpnext/patches/ @deepeshgarg007
erpnext/controllers/ @deepeshgarg007 @nextchamp-saqib @rohitwaghchaure
erpnext/patches/ @deepeshgarg007 @nextchamp-saqib
.github/ @ankush
pyproject.toml @ankush
.github/ @deepeshgarg007
pyproject.toml @phot0n

View File

@@ -65,7 +65,7 @@ New passwords will be created for the ERPNext "Administrator" user, the MariaDB
1. [Frappe School](https://frappe.school) - Learn Frappe Framework and ERPNext from the various courses by the maintainers or from the community.
2. [Official documentation](https://docs.erpnext.com/) - Extensive documentation for ERPNext.
3. [Discussion Forum](https://discuss.erpnext.com/) - Engage with community of ERPNext users and service providers.
4. [Telegram Group](https://t.me/erpnexthelp) - Get instant help from huge community of users.
4. [Telegram Group](https://erpnext_public.t.me) - Get instant help from huge community of users.
## Contributing

View File

@@ -1,8 +1,9 @@
import functools
import inspect
import frappe
__version__ = "14.0.0-dev"
__version__ = "15.0.0-dev"
def get_default_company(user=None):
@@ -120,12 +121,14 @@ def get_region(company=None):
You can also set global company flag in `frappe.flags.company`
"""
if company or frappe.flags.company:
return frappe.get_cached_value("Company", company or frappe.flags.company, "country")
elif frappe.flags.country:
return frappe.flags.country
else:
return frappe.get_system_settings("country")
if not company:
company = frappe.local.flags.company
if company:
return frappe.get_cached_value("Company", company, "country")
return frappe.flags.country or frappe.get_system_settings("country")
def allow_regional(fn):
@@ -136,6 +139,7 @@ def allow_regional(fn):
def myfunction():
pass"""
@functools.wraps(fn)
def caller(*args, **kwargs):
overrides = frappe.get_hooks("regional_overrides", {}).get(get_region())
function_path = f"{inspect.getmodule(fn).__name__}.{fn.__name__}"

View File

@@ -378,7 +378,7 @@ def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
return
# check if books nor frozen till endate:
if accounts_frozen_upto and (end_date) <= getdate(accounts_frozen_upto):
if accounts_frozen_upto and getdate(end_date) <= getdate(accounts_frozen_upto):
end_date = get_last_day(add_days(accounts_frozen_upto, 1))
if via_journal_entry:

View File

@@ -18,7 +18,6 @@
"root_type",
"report_type",
"account_currency",
"inter_company_account",
"column_break1",
"parent_account",
"account_type",
@@ -34,15 +33,11 @@
{
"fieldname": "properties",
"fieldtype": "Section Break",
"oldfieldtype": "Section Break",
"show_days": 1,
"show_seconds": 1
"oldfieldtype": "Section Break"
},
{
"fieldname": "column_break0",
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1,
"width": "50%"
},
{
@@ -53,9 +48,7 @@
"no_copy": 1,
"oldfieldname": "account_name",
"oldfieldtype": "Data",
"reqd": 1,
"show_days": 1,
"show_seconds": 1
"reqd": 1
},
{
"fieldname": "account_number",
@@ -63,17 +56,13 @@
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Account Number",
"read_only": 1,
"show_days": 1,
"show_seconds": 1
"read_only": 1
},
{
"default": "0",
"fieldname": "is_group",
"fieldtype": "Check",
"label": "Is Group",
"show_days": 1,
"show_seconds": 1
"label": "Is Group"
},
{
"fieldname": "company",
@@ -85,9 +74,7 @@
"options": "Company",
"read_only": 1,
"remember_last_selected_value": 1,
"reqd": 1,
"show_days": 1,
"show_seconds": 1
"reqd": 1
},
{
"fieldname": "root_type",
@@ -95,9 +82,7 @@
"in_standard_filter": 1,
"label": "Root Type",
"options": "\nAsset\nLiability\nIncome\nExpense\nEquity",
"read_only": 1,
"show_days": 1,
"show_seconds": 1
"read_only": 1
},
{
"fieldname": "report_type",
@@ -105,32 +90,18 @@
"in_standard_filter": 1,
"label": "Report Type",
"options": "\nBalance Sheet\nProfit and Loss",
"read_only": 1,
"show_days": 1,
"show_seconds": 1
"read_only": 1
},
{
"depends_on": "eval:doc.is_group==0",
"fieldname": "account_currency",
"fieldtype": "Link",
"label": "Currency",
"options": "Currency",
"show_days": 1,
"show_seconds": 1
},
{
"default": "0",
"fieldname": "inter_company_account",
"fieldtype": "Check",
"label": "Inter Company Account",
"show_days": 1,
"show_seconds": 1
"options": "Currency"
},
{
"fieldname": "column_break1",
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1,
"width": "50%"
},
{
@@ -142,9 +113,7 @@
"oldfieldtype": "Link",
"options": "Account",
"reqd": 1,
"search_index": 1,
"show_days": 1,
"show_seconds": 1
"search_index": 1
},
{
"description": "Setting Account Type helps in selecting this Account in transactions.",
@@ -154,9 +123,7 @@
"label": "Account Type",
"oldfieldname": "account_type",
"oldfieldtype": "Select",
"options": "\nAccumulated Depreciation\nAsset Received But Not Billed\nBank\nCash\nChargeable\nCapital Work in Progress\nCost of Goods Sold\nDepreciation\nEquity\nExpense Account\nExpenses Included In Asset Valuation\nExpenses Included In Valuation\nFixed Asset\nIncome Account\nPayable\nReceivable\nRound Off\nStock\nStock Adjustment\nStock Received But Not Billed\nService Received But Not Billed\nTax\nTemporary",
"show_days": 1,
"show_seconds": 1
"options": "\nAccumulated Depreciation\nAsset Received But Not Billed\nBank\nCash\nChargeable\nCapital Work in Progress\nCost of Goods Sold\nDepreciation\nEquity\nExpense Account\nExpenses Included In Asset Valuation\nExpenses Included In Valuation\nFixed Asset\nIncome Account\nPayable\nReceivable\nRound Off\nStock\nStock Adjustment\nStock Received But Not Billed\nService Received But Not Billed\nTax\nTemporary"
},
{
"description": "Rate at which this tax is applied",
@@ -164,9 +131,7 @@
"fieldtype": "Float",
"label": "Rate",
"oldfieldname": "tax_rate",
"oldfieldtype": "Currency",
"show_days": 1,
"show_seconds": 1
"oldfieldtype": "Currency"
},
{
"description": "If the account is frozen, entries are allowed to restricted users.",
@@ -175,17 +140,13 @@
"label": "Frozen",
"oldfieldname": "freeze_account",
"oldfieldtype": "Select",
"options": "No\nYes",
"show_days": 1,
"show_seconds": 1
"options": "No\nYes"
},
{
"fieldname": "balance_must_be",
"fieldtype": "Select",
"label": "Balance must be",
"options": "\nDebit\nCredit",
"show_days": 1,
"show_seconds": 1
"options": "\nDebit\nCredit"
},
{
"fieldname": "lft",
@@ -194,9 +155,7 @@
"label": "Lft",
"print_hide": 1,
"read_only": 1,
"search_index": 1,
"show_days": 1,
"show_seconds": 1
"search_index": 1
},
{
"fieldname": "rgt",
@@ -205,9 +164,7 @@
"label": "Rgt",
"print_hide": 1,
"read_only": 1,
"search_index": 1,
"show_days": 1,
"show_seconds": 1
"search_index": 1
},
{
"fieldname": "old_parent",
@@ -215,33 +172,27 @@
"hidden": 1,
"label": "Old Parent",
"print_hide": 1,
"read_only": 1,
"show_days": 1,
"show_seconds": 1
"read_only": 1
},
{
"default": "0",
"depends_on": "eval:(doc.report_type == 'Profit and Loss' && !doc.is_group)",
"fieldname": "include_in_gross",
"fieldtype": "Check",
"label": "Include in gross",
"show_days": 1,
"show_seconds": 1
"label": "Include in gross"
},
{
"default": "0",
"fieldname": "disabled",
"fieldtype": "Check",
"label": "Disable",
"show_days": 1,
"show_seconds": 1
"label": "Disable"
}
],
"icon": "fa fa-money",
"idx": 1,
"is_tree": 1,
"links": [],
"modified": "2020-06-11 15:15:54.338622",
"modified": "2023-04-11 16:08:46.983677",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Account",
@@ -301,5 +252,6 @@
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "ASC",
"states": [],
"track_changes": 1
}

View File

@@ -204,8 +204,11 @@ class Account(NestedSet):
)
def validate_account_currency(self):
self.currency_explicitly_specified = True
if not self.account_currency:
self.account_currency = frappe.get_cached_value("Company", self.company, "default_currency")
self.currency_explicitly_specified = False
gl_currency = frappe.db.get_value("GL Entry", {"account": self.name}, "account_currency")
@@ -251,8 +254,10 @@ class Account(NestedSet):
{
"company": company,
# parent account's currency should be passed down to child account's curreny
# if it is None, it picks it up from default company currency, which might be unintended
"account_currency": erpnext.get_company_currency(company),
# if currency explicitly specified by user, child will inherit. else, default currency will be used.
"account_currency": self.account_currency
if self.currency_explicitly_specified
else erpnext.get_company_currency(company),
"parent_account": parent_acc_name_map[company],
}
)
@@ -394,7 +399,13 @@ def update_account_number(name, account_name, account_number=None, from_descenda
if ancestors and not allow_independent_account_creation:
for ancestor in ancestors:
if frappe.db.get_value("Account", {"account_name": old_acc_name, "company": ancestor}, "name"):
old_name = frappe.db.get_value(
"Account",
{"account_number": old_acc_number, "account_name": old_acc_name, "company": ancestor},
"name",
)
if old_name:
# same account in parent company exists
allow_child_account_creation = _("Allow Account Creation Against Child Company")

View File

@@ -56,36 +56,41 @@ frappe.treeview_settings["Account"] = {
accounts = nodes;
}
const get_balances = frappe.call({
method: 'erpnext.accounts.utils.get_account_balances',
args: {
accounts: accounts,
company: cur_tree.args.company
},
});
frappe.db.get_single_value("Accounts Settings", "show_balance_in_coa").then((value) => {
if(value) {
get_balances.then(r => {
if (!r.message || r.message.length == 0) return;
const get_balances = frappe.call({
method: 'erpnext.accounts.utils.get_account_balances',
args: {
accounts: accounts,
company: cur_tree.args.company
},
});
for (let account of r.message) {
get_balances.then(r => {
if (!r.message || r.message.length == 0) return;
const node = cur_tree.nodes && cur_tree.nodes[account.value];
if (!node || node.is_root) continue;
for (let account of r.message) {
// show Dr if positive since balance is calculated as debit - credit else show Cr
const balance = account.balance_in_account_currency || account.balance;
const dr_or_cr = balance > 0 ? "Dr": "Cr";
const format = (value, currency) => format_currency(Math.abs(value), currency);
const node = cur_tree.nodes && cur_tree.nodes[account.value];
if (!node || node.is_root) continue;
if (account.balance!==undefined) {
node.parent && node.parent.find('.balance-area').remove();
$('<span class="balance-area pull-right">'
+ (account.balance_in_account_currency ?
(format(account.balance_in_account_currency, account.account_currency) + " / ") : "")
+ format(account.balance, account.company_currency)
+ " " + dr_or_cr
+ '</span>').insertBefore(node.$ul);
}
// show Dr if positive since balance is calculated as debit - credit else show Cr
const balance = account.balance_in_account_currency || account.balance;
const dr_or_cr = balance > 0 ? "Dr": "Cr";
const format = (value, currency) => format_currency(Math.abs(value), currency);
if (account.balance!==undefined) {
node.parent && node.parent.find('.balance-area').remove();
$('<span class="balance-area pull-right">'
+ (account.balance_in_account_currency ?
(format(account.balance_in_account_currency, account.account_currency) + " / ") : "")
+ format(account.balance, account.company_currency)
+ " " + dr_or_cr
+ '</span>').insertBefore(node.$ul);
}
}
});
}
});
},

View File

@@ -29,6 +29,7 @@ def create_charts(
"root_type",
"is_group",
"tax_rate",
"account_currency",
]:
account_number = cstr(child.get("account_number")).strip()
@@ -95,7 +96,17 @@ def identify_is_group(child):
is_group = child.get("is_group")
elif len(
set(child.keys())
- set(["account_name", "account_type", "root_type", "is_group", "tax_rate", "account_number"])
- set(
[
"account_name",
"account_type",
"root_type",
"is_group",
"tax_rate",
"account_number",
"account_currency",
]
)
):
is_group = 1
else:
@@ -185,6 +196,7 @@ def get_account_tree_from_existing_company(existing_company):
"root_type",
"tax_rate",
"account_number",
"account_currency",
],
order_by="lft, rgt",
)
@@ -267,6 +279,7 @@ def build_tree_from_json(chart_template, chart_data=None, from_coa_importer=Fals
"root_type",
"is_group",
"tax_rate",
"account_currency",
]:
continue

View File

@@ -1,38 +1,38 @@
{
"country_code": "de",
"name": "SKR03 mit Kontonummern",
"tree": {
"Aktiva": {
"is_group": 1,
"country_code": "de",
"name": "SKR03 mit Kontonummern",
"tree": {
"Aktiva": {
"is_group": 1,
"root_type": "Asset",
"A - Anlagevermögen": {
"is_group": 1,
"EDV-Software": {
"account_number": "0027",
"account_type": "Fixed Asset"
},
"Gesch\u00e4ftsausstattung": {
"account_number": "0410",
"account_type": "Fixed Asset"
},
"B\u00fcroeinrichtung": {
"account_number": "0420",
"account_type": "Fixed Asset"
},
"Darlehen": {
"account_number": "0565"
},
"Maschinen": {
"account_number": "0210",
"account_type": "Fixed Asset"
},
"Betriebsausstattung": {
"account_number": "0400",
"account_type": "Fixed Asset"
},
"Ladeneinrichtung": {
"account_number": "0430",
"account_type": "Fixed Asset"
"A - Anlagevermögen": {
"is_group": 1,
"EDV-Software": {
"account_number": "0027",
"account_type": "Fixed Asset"
},
"Geschäftsausstattung": {
"account_number": "0410",
"account_type": "Fixed Asset"
},
"Büroeinrichtung": {
"account_number": "0420",
"account_type": "Fixed Asset"
},
"Darlehen": {
"account_number": "0565"
},
"Maschinen": {
"account_number": "0210",
"account_type": "Fixed Asset"
},
"Betriebsausstattung": {
"account_number": "0400",
"account_type": "Fixed Asset"
},
"Ladeneinrichtung": {
"account_number": "0430",
"account_type": "Fixed Asset"
},
"Accumulated Depreciation": {
"account_type": "Accumulated Depreciation"
@@ -60,36 +60,46 @@
"Durchlaufende Posten": {
"account_number": "1590"
},
"Gewinnermittlung \u00a74/3 nicht Ergebniswirksam": {
"Verrechnungskonto Gewinnermittlung § 4 Abs. 3 EStG, nicht ergebniswirksam": {
"account_number": "1371"
},
"Abziehbare Vorsteuer": {
"account_type": "Tax",
"is_group": 1,
"Abziehbare Vorsteuer 7%": {
"account_number": "1571"
"Abziehbare Vorsteuer 7 %": {
"account_number": "1571",
"account_type": "Tax",
"tax_rate": 7.0
},
"Abziehbare Vorsteuer 19%": {
"account_number": "1576"
"Abziehbare Vorsteuer 19 %": {
"account_number": "1576",
"account_type": "Tax",
"tax_rate": 19.0
},
"Abziehbare Vorsteuer nach \u00a713b UStG 19%": {
"account_number": "1577"
},
"Leistungen \u00a713b UStG 19% Vorsteuer, 19% Umsatzsteuer": {
"account_number": "3120"
"Abziehbare Vorsteuer nach § 13b UStG 19 %": {
"account_number": "1577",
"account_type": "Tax",
"tax_rate": 19.0
}
}
},
"III. Wertpapiere": {
"is_group": 1
"is_group": 1,
"Anteile an verbundenen Unternehmen (Umlaufvermögen)": {
"account_number": "1340"
},
"Anteile an herrschender oder mit Mehrheit beteiligter Gesellschaft": {
"account_number": "1344"
},
"Sonstige Wertpapiere": {
"account_number": "1348"
}
},
"IV. Kassenbestand, Bundesbankguthaben, Guthaben bei Kreditinstituten und Schecks.": {
"is_group": 1,
"Kasse": {
"account_type": "Cash",
"is_group": 1,
"account_type": "Cash",
"Kasse": {
"is_group": 1,
"account_number": "1000",
"account_type": "Cash"
}
@@ -111,21 +121,21 @@
"C - Rechnungsabgrenzungsposten": {
"is_group": 1,
"Aktive Rechnungsabgrenzung": {
"account_number": "0980"
"account_number": "0980"
}
},
"D - Aktive latente Steuern": {
"is_group": 1,
"Aktive latente Steuern": {
"account_number": "0983"
"account_number": "0983"
}
},
"E - Aktiver Unterschiedsbetrag aus der Vermögensverrechnung": {
"is_group": 1
}
},
"Passiva": {
"is_group": 1,
},
"Passiva": {
"is_group": 1,
"root_type": "Liability",
"A. Eigenkapital": {
"is_group": 1,
@@ -200,26 +210,32 @@
},
"Umsatzsteuer": {
"is_group": 1,
"account_type": "Tax",
"Umsatzsteuer 7%": {
"account_number": "1771"
"Umsatzsteuer 7 %": {
"account_number": "1771",
"account_type": "Tax",
"tax_rate": 7.0
},
"Umsatzsteuer 19%": {
"account_number": "1776"
"Umsatzsteuer 19 %": {
"account_number": "1776",
"account_type": "Tax",
"tax_rate": 19.0
},
"Umsatzsteuer-Vorauszahlung": {
"account_number": "1780"
"account_number": "1780",
"account_type": "Tax"
},
"Umsatzsteuer-Vorauszahlung 1/11": {
"account_number": "1781"
},
"Umsatzsteuer \u00a7 13b UStG 19%": {
"account_number": "1787"
"Umsatzsteuer nach § 13b UStG 19 %": {
"account_number": "1787",
"account_type": "Tax",
"tax_rate": 19.0
},
"Umsatzsteuer Vorjahr": {
"account_number": "1790"
},
"Umsatzsteuer fr\u00fchere Jahre": {
"Umsatzsteuer frühere Jahre": {
"account_number": "1791"
}
}
@@ -234,44 +250,56 @@
"E. Passive latente Steuern": {
"is_group": 1
}
},
"Erl\u00f6se u. Ertr\u00e4ge 2/8": {
"is_group": 1,
"root_type": "Income",
"Erl\u00f6skonten 8": {
},
"Erlöse u. Erträge 2/8": {
"is_group": 1,
"root_type": "Income",
"Erlöskonten 8": {
"is_group": 1,
"Erl\u00f6se": {
"account_number": "8200",
"account_type": "Income Account"
},
"Erl\u00f6se USt. 19%": {
"account_number": "8400",
"account_type": "Income Account"
},
"Erl\u00f6se USt. 7%": {
"account_number": "8300",
"account_type": "Income Account"
}
},
"Ertragskonten 2": {
"is_group": 1,
"sonstige Zinsen und \u00e4hnliche Ertr\u00e4ge": {
"account_number": "2650",
"account_type": "Income Account"
},
"Au\u00dferordentliche Ertr\u00e4ge": {
"account_number": "2500",
"account_type": "Income Account"
},
"Sonstige Ertr\u00e4ge": {
"account_number": "2700",
"account_type": "Income Account"
}
}
},
"Aufwendungen 2/4": {
"is_group": 1,
"Erlöse": {
"account_number": "8200",
"account_type": "Income Account"
},
"Erlöse USt. 19 %": {
"account_number": "8400",
"account_type": "Income Account"
},
"Erlöse USt. 7 %": {
"account_number": "8300",
"account_type": "Income Account"
}
},
"Ertragskonten 2": {
"is_group": 1,
"sonstige Zinsen und ähnliche Erträge": {
"account_number": "2650",
"account_type": "Income Account"
},
"Außerordentliche Erträge": {
"account_number": "2500",
"account_type": "Income Account"
},
"Sonstige Erträge": {
"account_number": "2700",
"account_type": "Income Account"
}
}
},
"Aufwendungen 2/4": {
"is_group": 1,
"root_type": "Expense",
"Fremdleistungen": {
"account_number": "3100",
"account_type": "Expense Account"
},
"Fremdleistungen ohne Vorsteuer": {
"account_number": "3109",
"account_type": "Expense Account"
},
"Bauleistungen eines im Inland ansässigen Unternehmers 19 % Vorsteuer und 19 % Umsatzsteuer": {
"account_number": "3120",
"account_type": "Expense Account"
},
"Wareneingang": {
"account_number": "3200"
},
@@ -298,234 +326,234 @@
"Gegenkonto 4996-4998": {
"account_number": "4999"
},
"Abschreibungen": {
"is_group": 1,
"Abschreibungen": {
"is_group": 1,
"Abschreibungen auf Sachanlagen (ohne AfA auf Kfz und Gebäude)": {
"account_number": "4830",
"account_type": "Accumulated Depreciation"
"account_number": "4830",
"account_type": "Accumulated Depreciation"
},
"Abschreibungen auf Gebäude": {
"account_number": "4831",
"account_type": "Depreciation"
"account_number": "4831",
"account_type": "Depreciation"
},
"Abschreibungen auf Kfz": {
"account_number": "4832",
"account_type": "Depreciation"
"account_number": "4832",
"account_type": "Depreciation"
},
"Sofortabschreibung GWG": {
"account_number": "4855",
"account_type": "Expense Account"
"account_number": "4855",
"account_type": "Expense Account"
}
},
"Kfz-Kosten": {
"is_group": 1,
"Kfz-Steuer": {
"account_number": "4510",
"account_type": "Expense Account"
},
"Kfz-Versicherungen": {
"account_number": "4520",
"account_type": "Expense Account"
},
"laufende Kfz-Betriebskosten": {
"account_number": "4530",
"account_type": "Expense Account"
},
"Kfz-Reparaturen": {
"account_number": "4540",
"account_type": "Expense Account"
},
"Fremdfahrzeuge": {
"account_number": "4570",
"account_type": "Expense Account"
},
"sonstige Kfz-Kosten": {
"account_number": "4580",
"account_type": "Expense Account"
}
},
"Personalkosten": {
"is_group": 1,
"Geh\u00e4lter": {
"account_number": "4120",
"account_type": "Expense Account"
},
"gesetzliche soziale Aufwendungen": {
"account_number": "4130",
"account_type": "Expense Account"
},
"Aufwendungen f\u00fcr Altersvorsorge": {
"account_number": "4165",
"account_type": "Expense Account"
},
"Verm\u00f6genswirksame Leistungen": {
"account_number": "4170",
"account_type": "Expense Account"
},
"Aushilfsl\u00f6hne": {
"account_number": "4190",
"account_type": "Expense Account"
}
},
"Raumkosten": {
"is_group": 1,
"Miete und Nebenkosten": {
"account_number": "4210",
"account_type": "Expense Account"
},
"Gas, Wasser, Strom (Verwaltung, Vertrieb)": {
"account_number": "4240",
"account_type": "Expense Account"
},
"Reinigung": {
"account_number": "4250",
"account_type": "Expense Account"
}
},
"Reparatur/Instandhaltung": {
"is_group": 1,
"Reparatur u. Instandh. von Anlagen/Maschinen u. Betriebs- u. Gesch\u00e4ftsausst.": {
"account_number": "4805",
"account_type": "Expense Account"
}
},
"Versicherungsbeitr\u00e4ge": {
"is_group": 1,
"Versicherungen": {
"account_number": "4360",
"account_type": "Expense Account"
},
"Beitr\u00e4ge": {
"account_number": "4380",
"account_type": "Expense Account"
},
"sonstige Ausgaben": {
"account_number": "4390",
"account_type": "Expense Account"
},
"steuerlich abzugsf\u00e4hige Versp\u00e4tungszuschl\u00e4ge und Zwangsgelder": {
"account_number": "4396",
"account_type": "Expense Account"
}
},
"Werbe-/Reisekosten": {
"is_group": 1,
"Werbekosten": {
"account_number": "4610",
"account_type": "Expense Account"
},
"Aufmerksamkeiten": {
"account_number": "4653",
"account_type": "Expense Account"
},
"nicht abzugsf\u00e4hige Betriebsausg. aus Werbe-, Repr\u00e4s.- u. Reisekosten": {
"account_number": "4665",
"account_type": "Expense Account"
},
"Reisekosten Unternehmer": {
"account_number": "4670",
"account_type": "Expense Account"
}
},
"verschiedene Kosten": {
"is_group": 1,
"Porto": {
"account_number": "4910",
"account_type": "Expense Account"
},
"Telekom": {
"account_number": "4920",
"account_type": "Expense Account"
},
"Mobilfunk D2": {
"account_number": "4921",
"account_type": "Expense Account"
},
"Internet": {
"account_number": "4922",
"account_type": "Expense Account"
},
"B\u00fcrobedarf": {
"account_number": "4930",
"account_type": "Expense Account"
},
"Zeitschriften, B\u00fccher": {
"account_number": "4940",
"account_type": "Expense Account"
},
"Fortbildungskosten": {
"account_number": "4945",
"account_type": "Expense Account"
},
"Buchf\u00fchrungskosten": {
"account_number": "4955",
"account_type": "Expense Account"
},
"Abschlu\u00df- u. Pr\u00fcfungskosten": {
"account_number": "4957",
"account_type": "Expense Account"
},
"Nebenkosten des Geldverkehrs": {
"account_number": "4970",
"account_type": "Expense Account"
},
"Werkzeuge und Kleinger\u00e4te": {
"account_number": "4985",
"account_type": "Expense Account"
}
},
"Zinsaufwendungen": {
"is_group": 1,
"Zinsaufwendungen f\u00fcr kurzfristige Verbindlichkeiten": {
"account_number": "2110",
"account_type": "Expense Account"
},
"Zinsaufwendungen f\u00fcr KFZ Finanzierung": {
"account_number": "2121",
"account_type": "Expense Account"
}
}
},
"Anfangsbestand 9": {
"is_group": 1,
"root_type": "Equity",
"Saldenvortragskonten": {
"is_group": 1,
"Saldenvortrag Sachkonten": {
"account_number": "9000"
},
"Saldenvortr\u00e4ge Debitoren": {
"account_number": "9008"
},
"Saldenvortr\u00e4ge Kreditoren": {
"account_number": "9009"
}
}
},
"Privatkonten 1": {
"is_group": 1,
"root_type": "Equity",
"Privatentnahmen/-einlagen": {
"is_group": 1,
"Privatentnahme allgemein": {
"account_number": "1800"
},
"Privatsteuern": {
"account_number": "1810"
},
"Sonderausgaben beschr\u00e4nkt abzugsf\u00e4hig": {
"account_number": "1820"
},
"Sonderausgaben unbeschr\u00e4nkt abzugsf\u00e4hig": {
"account_number": "1830"
},
"Au\u00dfergew\u00f6hnliche Belastungen": {
"account_number": "1850"
},
"Privateinlagen": {
"account_number": "1890"
}
}
}
}
},
"Kfz-Kosten": {
"is_group": 1,
"Kfz-Steuer": {
"account_number": "4510",
"account_type": "Expense Account"
},
"Kfz-Versicherungen": {
"account_number": "4520",
"account_type": "Expense Account"
},
"laufende Kfz-Betriebskosten": {
"account_number": "4530",
"account_type": "Expense Account"
},
"Kfz-Reparaturen": {
"account_number": "4540",
"account_type": "Expense Account"
},
"Fremdfahrzeuge": {
"account_number": "4570",
"account_type": "Expense Account"
},
"sonstige Kfz-Kosten": {
"account_number": "4580",
"account_type": "Expense Account"
}
},
"Personalkosten": {
"is_group": 1,
"Gehälter": {
"account_number": "4120",
"account_type": "Expense Account"
},
"gesetzliche soziale Aufwendungen": {
"account_number": "4130",
"account_type": "Expense Account"
},
"Aufwendungen für Altersvorsorge": {
"account_number": "4165",
"account_type": "Expense Account"
},
"Vermögenswirksame Leistungen": {
"account_number": "4170",
"account_type": "Expense Account"
},
"Aushilfslöhne": {
"account_number": "4190",
"account_type": "Expense Account"
}
},
"Raumkosten": {
"is_group": 1,
"Miete und Nebenkosten": {
"account_number": "4210",
"account_type": "Expense Account"
},
"Gas, Wasser, Strom (Verwaltung, Vertrieb)": {
"account_number": "4240",
"account_type": "Expense Account"
},
"Reinigung": {
"account_number": "4250",
"account_type": "Expense Account"
}
},
"Reparatur/Instandhaltung": {
"is_group": 1,
"Reparaturen und Instandhaltungen von anderen Anlagen und Betriebs- und Geschäftsausstattung": {
"account_number": "4805",
"account_type": "Expense Account"
}
},
"Versicherungsbeiträge": {
"is_group": 1,
"Versicherungen": {
"account_number": "4360",
"account_type": "Expense Account"
},
"Beiträge": {
"account_number": "4380",
"account_type": "Expense Account"
},
"sonstige Ausgaben": {
"account_number": "4390",
"account_type": "Expense Account"
},
"steuerlich abzugsfähige Verspätungszuschläge und Zwangsgelder": {
"account_number": "4396",
"account_type": "Expense Account"
}
},
"Werbe-/Reisekosten": {
"is_group": 1,
"Werbekosten": {
"account_number": "4610",
"account_type": "Expense Account"
},
"Aufmerksamkeiten": {
"account_number": "4653",
"account_type": "Expense Account"
},
"nicht abzugsfähige Betriebsausg. aus Werbe-, Repräs.- u. Reisekosten": {
"account_number": "4665",
"account_type": "Expense Account"
},
"Reisekosten Unternehmer": {
"account_number": "4670",
"account_type": "Expense Account"
}
},
"verschiedene Kosten": {
"is_group": 1,
"Porto": {
"account_number": "4910",
"account_type": "Expense Account"
},
"Telekom": {
"account_number": "4920",
"account_type": "Expense Account"
},
"Mobilfunk D2": {
"account_number": "4921",
"account_type": "Expense Account"
},
"Internet": {
"account_number": "4922",
"account_type": "Expense Account"
},
"Bürobedarf": {
"account_number": "4930",
"account_type": "Expense Account"
},
"Zeitschriften, Bücher": {
"account_number": "4940",
"account_type": "Expense Account"
},
"Fortbildungskosten": {
"account_number": "4945",
"account_type": "Expense Account"
},
"Buchführungskosten": {
"account_number": "4955",
"account_type": "Expense Account"
},
"Abschluß- u. Prüfungskosten": {
"account_number": "4957",
"account_type": "Expense Account"
},
"Nebenkosten des Geldverkehrs": {
"account_number": "4970",
"account_type": "Expense Account"
},
"Werkzeuge und Kleingeräte": {
"account_number": "4985",
"account_type": "Expense Account"
}
},
"Zinsaufwendungen": {
"is_group": 1,
"Zinsaufwendungen für kurzfristige Verbindlichkeiten": {
"account_number": "2110",
"account_type": "Expense Account"
},
"Zinsaufwendungen für KFZ Finanzierung": {
"account_number": "2121",
"account_type": "Expense Account"
}
}
},
"Anfangsbestand 9": {
"is_group": 1,
"root_type": "Equity",
"Saldenvortragskonten": {
"is_group": 1,
"Saldenvortrag Sachkonten": {
"account_number": "9000"
},
"Saldenvorträge Debitoren": {
"account_number": "9008"
},
"Saldenvorträge Kreditoren": {
"account_number": "9009"
}
}
},
"Privatkonten 1": {
"is_group": 1,
"root_type": "Equity",
"Privatentnahmen/-einlagen": {
"is_group": 1,
"Privatentnahme allgemein": {
"account_number": "1800"
},
"Privatsteuern": {
"account_number": "1810"
},
"Sonderausgaben beschränkt abzugsfähig": {
"account_number": "1820"
},
"Sonderausgaben unbeschränkt abzugsfähig": {
"account_number": "1830"
},
"Außergewöhnliche Belastungen": {
"account_number": "1850"
},
"Privateinlagen": {
"account_number": "1890"
}
}
}
}
}

View File

@@ -5,10 +5,13 @@
import unittest
import frappe
from frappe.test_runner import make_test_records
from erpnext.accounts.doctype.account.account import merge_account, update_account_number
from erpnext.stock import get_company_default_inventory_account, get_warehouse_account
test_dependencies = ["Company"]
class TestAccount(unittest.TestCase):
def test_rename_account(self):
@@ -188,6 +191,58 @@ class TestAccount(unittest.TestCase):
frappe.delete_doc("Account", "1234 - Test Rename Sync Account - _TC4")
frappe.delete_doc("Account", "1234 - Test Rename Sync Account - _TC5")
def test_account_currency_sync(self):
"""
In a parent->child company setup, child should inherit parent account currency if explicitly specified.
"""
make_test_records("Company")
frappe.local.flags.pop("ignore_root_company_validation", None)
def create_bank_account():
acc = frappe.new_doc("Account")
acc.account_name = "_Test Bank JPY"
acc.parent_account = "Temporary Accounts - _TC6"
acc.company = "_Test Company 6"
return acc
acc = create_bank_account()
# Explicitly set currency
acc.account_currency = "JPY"
acc.insert()
self.assertTrue(
frappe.db.exists(
{
"doctype": "Account",
"account_name": "_Test Bank JPY",
"account_currency": "JPY",
"company": "_Test Company 7",
}
)
)
frappe.delete_doc("Account", "_Test Bank JPY - _TC6")
frappe.delete_doc("Account", "_Test Bank JPY - _TC7")
acc = create_bank_account()
# default currency is used
acc.insert()
self.assertTrue(
frappe.db.exists(
{
"doctype": "Account",
"account_name": "_Test Bank JPY",
"account_currency": "USD",
"company": "_Test Company 7",
}
)
)
frappe.delete_doc("Account", "_Test Bank JPY - _TC6")
frappe.delete_doc("Account", "_Test Bank JPY - _TC7")
def test_child_company_account_rename_sync(self):
frappe.local.flags.pop("ignore_root_company_validation", None)
@@ -297,7 +352,7 @@ def _make_test_records(verbose=None):
# fixed asset depreciation
["_Test Fixed Asset", "Current Assets", 0, "Fixed Asset", None],
["_Test Accumulated Depreciations", "Current Assets", 0, "Accumulated Depreciation", None],
["_Test Depreciations", "Expenses", 0, None, None],
["_Test Depreciations", "Expenses", 0, "Depreciation", None],
["_Test Gain/Loss on Asset Disposal", "Expenses", 0, None, None],
# Receivable / Payable Account
["_Test Receivable", "Current Assets", 0, "Receivable", None],

View File

@@ -0,0 +1,8 @@
// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
// frappe.ui.form.on("Account Closing Balance", {
// refresh(frm) {
// },
// });

View File

@@ -0,0 +1,164 @@
{
"actions": [],
"creation": "2023-02-21 15:20:59.586811",
"default_view": "List",
"doctype": "DocType",
"document_type": "Document",
"engine": "InnoDB",
"field_order": [
"closing_date",
"account",
"cost_center",
"debit",
"credit",
"account_currency",
"debit_in_account_currency",
"credit_in_account_currency",
"project",
"company",
"finance_book",
"period_closing_voucher",
"is_period_closing_voucher_entry"
],
"fields": [
{
"fieldname": "closing_date",
"fieldtype": "Date",
"in_filter": 1,
"in_list_view": 1,
"label": "Closing Date",
"oldfieldname": "posting_date",
"oldfieldtype": "Date",
"search_index": 1
},
{
"fieldname": "account",
"fieldtype": "Link",
"in_filter": 1,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Account",
"oldfieldname": "account",
"oldfieldtype": "Link",
"options": "Account",
"search_index": 1
},
{
"fieldname": "cost_center",
"fieldtype": "Link",
"in_filter": 1,
"in_list_view": 1,
"label": "Cost Center",
"oldfieldname": "cost_center",
"oldfieldtype": "Link",
"options": "Cost Center"
},
{
"fieldname": "debit",
"fieldtype": "Currency",
"label": "Debit Amount",
"oldfieldname": "debit",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency"
},
{
"fieldname": "credit",
"fieldtype": "Currency",
"label": "Credit Amount",
"oldfieldname": "credit",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency"
},
{
"fieldname": "account_currency",
"fieldtype": "Link",
"label": "Account Currency",
"options": "Currency"
},
{
"fieldname": "debit_in_account_currency",
"fieldtype": "Currency",
"label": "Debit Amount in Account Currency",
"options": "account_currency"
},
{
"fieldname": "credit_in_account_currency",
"fieldtype": "Currency",
"label": "Credit Amount in Account Currency",
"options": "account_currency"
},
{
"fieldname": "project",
"fieldtype": "Link",
"label": "Project",
"options": "Project"
},
{
"fieldname": "company",
"fieldtype": "Link",
"in_filter": 1,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Company",
"oldfieldname": "company",
"oldfieldtype": "Link",
"options": "Company",
"search_index": 1
},
{
"fieldname": "finance_book",
"fieldtype": "Link",
"label": "Finance Book",
"options": "Finance Book"
},
{
"fieldname": "period_closing_voucher",
"fieldtype": "Link",
"in_standard_filter": 1,
"label": "Period Closing Voucher",
"options": "Period Closing Voucher",
"search_index": 1
},
{
"default": "0",
"fieldname": "is_period_closing_voucher_entry",
"fieldtype": "Check",
"label": "Is Period Closing Voucher Entry"
}
],
"icon": "fa fa-list",
"in_create": 1,
"links": [],
"modified": "2023-03-06 08:56:36.393237",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Account Closing Balance",
"owner": "Administrator",
"permissions": [
{
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts User"
},
{
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts Manager"
},
{
"export": 1,
"read": 1,
"report": 1,
"role": "Auditor"
}
],
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}

View File

@@ -0,0 +1,128 @@
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
import frappe
from frappe.model.document import Document
from frappe.utils import cint, cstr
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
get_accounting_dimensions,
)
class AccountClosingBalance(Document):
pass
def make_closing_entries(closing_entries, voucher_name):
accounting_dimensions = get_accounting_dimensions()
company = closing_entries[0].get("company")
closing_date = closing_entries[0].get("closing_date")
previous_closing_entries = get_previous_closing_entries(
company, closing_date, accounting_dimensions
)
combined_entries = closing_entries + previous_closing_entries
merged_entries = aggregate_with_last_account_closing_balance(
combined_entries, accounting_dimensions
)
for key, value in merged_entries.items():
cle = frappe.new_doc("Account Closing Balance")
cle.update(value)
cle.update(value["dimensions"])
cle.update(
{
"period_closing_voucher": voucher_name,
"closing_date": closing_date,
}
)
cle.flags.ignore_permissions = True
cle.submit()
def aggregate_with_last_account_closing_balance(entries, accounting_dimensions):
merged_entries = {}
for entry in entries:
key, key_values = generate_key(entry, accounting_dimensions)
merged_entries.setdefault(
key,
{
"debit": 0,
"credit": 0,
"debit_in_account_currency": 0,
"credit_in_account_currency": 0,
},
)
merged_entries[key]["dimensions"] = key_values
merged_entries[key]["debit"] += entry.get("debit")
merged_entries[key]["credit"] += entry.get("credit")
merged_entries[key]["debit_in_account_currency"] += entry.get("debit_in_account_currency")
merged_entries[key]["credit_in_account_currency"] += entry.get("credit_in_account_currency")
return merged_entries
def generate_key(entry, accounting_dimensions):
key = [
cstr(entry.get("account")),
cstr(entry.get("account_currency")),
cstr(entry.get("cost_center")),
cstr(entry.get("project")),
cstr(entry.get("finance_book")),
cint(entry.get("is_period_closing_voucher_entry")),
]
key_values = {
"company": cstr(entry.get("company")),
"account": cstr(entry.get("account")),
"account_currency": cstr(entry.get("account_currency")),
"cost_center": cstr(entry.get("cost_center")),
"project": cstr(entry.get("project")),
"finance_book": cstr(entry.get("finance_book")),
"is_period_closing_voucher_entry": cint(entry.get("is_period_closing_voucher_entry")),
}
for dimension in accounting_dimensions:
key.append(cstr(entry.get(dimension)))
key_values[dimension] = cstr(entry.get(dimension))
return tuple(key), key_values
def get_previous_closing_entries(company, closing_date, accounting_dimensions):
entries = []
last_period_closing_voucher = frappe.db.get_all(
"Period Closing Voucher",
filters={"docstatus": 1, "company": company, "posting_date": ("<", closing_date)},
fields=["name"],
order_by="posting_date desc",
limit=1,
)
if last_period_closing_voucher:
account_closing_balance = frappe.qb.DocType("Account Closing Balance")
query = frappe.qb.from_(account_closing_balance).select(
account_closing_balance.company,
account_closing_balance.account,
account_closing_balance.account_currency,
account_closing_balance.debit,
account_closing_balance.credit,
account_closing_balance.debit_in_account_currency,
account_closing_balance.credit_in_account_currency,
account_closing_balance.cost_center,
account_closing_balance.project,
account_closing_balance.finance_book,
account_closing_balance.is_period_closing_voucher_entry,
)
for dimension in accounting_dimensions:
query = query.select(account_closing_balance[dimension])
query = query.where(
account_closing_balance.period_closing_voucher == last_period_closing_voucher[0].name
)
entries = query.run(as_dict=1)
return entries

View File

@@ -0,0 +1,9 @@
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
# import frappe
from frappe.tests.utils import FrappeTestCase
class TestAccountClosingBalance(FrappeTestCase):
pass

View File

@@ -50,13 +50,15 @@ class AccountingDimension(Document):
if frappe.flags.in_test:
make_dimension_in_accounting_doctypes(doc=self)
else:
frappe.enqueue(make_dimension_in_accounting_doctypes, doc=self, queue="long")
frappe.enqueue(
make_dimension_in_accounting_doctypes, doc=self, queue="long", enqueue_after_commit=True
)
def on_trash(self):
if frappe.flags.in_test:
delete_accounting_dimension(doc=self)
else:
frappe.enqueue(delete_accounting_dimension, doc=self, queue="long")
frappe.enqueue(delete_accounting_dimension, doc=self, queue="long", enqueue_after_commit=True)
def set_fieldname_and_label(self):
if not self.label:

View File

@@ -19,8 +19,8 @@
"column_break_17",
"enable_common_party_accounting",
"allow_multi_currency_invoices_against_single_party_account",
"report_setting_section",
"use_custom_cash_flow",
"journals_section",
"merge_similar_account_heads",
"deferred_accounting_settings_section",
"book_deferred_entries_based_on",
"column_break_18",
@@ -31,12 +31,16 @@
"determine_address_tax_category_from",
"column_break_19",
"add_taxes_from_item_tax_template",
"book_tax_discount_loss",
"print_settings",
"show_inclusive_tax_in_print",
"show_taxes_as_table_in_print",
"column_break_12",
"show_payment_schedule_in_print",
"currency_exchange_section",
"allow_stale",
"section_break_jpd0",
"auto_reconcile_payments",
"stale_days",
"invoicing_settings_tab",
"accounts_transactions_settings_section",
@@ -56,7 +60,8 @@
"acc_frozen_upto",
"column_break_25",
"frozen_accounts_modifier",
"report_settings_sb"
"tab_break_dpet",
"show_balance_in_coa"
],
"fields": [
{
@@ -167,20 +172,9 @@
"fieldtype": "Int",
"label": "Stale Days"
},
{
"fieldname": "report_settings_sb",
"fieldtype": "Section Break",
"label": "Report Settings"
},
{
"default": "0",
"description": "Only select this if you have set up the Cash Flow Mapper documents",
"fieldname": "use_custom_cash_flow",
"fieldtype": "Check",
"label": "Enable Custom Cash Flow Format"
},
{
"default": "0",
"description": "Payment Terms from orders will be fetched into the invoices as is",
"fieldname": "automatically_fetch_payment_terms",
"fieldtype": "Check",
"label": "Automatically Fetch Payment Terms from Order"
@@ -336,17 +330,59 @@
"fieldtype": "Tab Break",
"label": "POS"
},
{
"fieldname": "report_setting_section",
"fieldtype": "Section Break",
"label": "Report Setting"
},
{
"default": "0",
"description": "Enabling this will allow creation of multi-currency invoices against single party account in company currency",
"fieldname": "allow_multi_currency_invoices_against_single_party_account",
"fieldtype": "Check",
"label": "Allow multi-currency invoices against single party account "
},
{
"fieldname": "tab_break_dpet",
"fieldtype": "Tab Break",
"label": "Chart Of Accounts"
},
{
"default": "1",
"fieldname": "show_balance_in_coa",
"fieldtype": "Check",
"label": "Show Balances in Chart Of Accounts"
},
{
"default": "0",
"description": "Split Early Payment Discount Loss into Income and Tax Loss",
"fieldname": "book_tax_discount_loss",
"fieldtype": "Check",
"label": "Book Tax Loss on Early Payment Discount"
},
{
"fieldname": "journals_section",
"fieldtype": "Section Break",
"label": "Journals"
},
{
"default": "0",
"description": "Rows with Same Account heads will be merged on Ledger",
"fieldname": "merge_similar_account_heads",
"fieldtype": "Check",
"label": "Merge Similar Account Heads"
},
{
"fieldname": "section_break_jpd0",
"fieldtype": "Section Break",
"label": "Payment Reconciliations"
},
{
"default": "0",
"fieldname": "auto_reconcile_payments",
"fieldtype": "Check",
"label": "Auto Reconcile Payments"
},
{
"default": "0",
"fieldname": "show_taxes_as_table_in_print",
"fieldtype": "Check",
"label": "Show Taxes as Table in Print"
}
],
"icon": "icon-cog",
@@ -354,7 +390,7 @@
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2022-11-27 21:49:52.538655",
"modified": "2023-06-13 18:47:46.430291",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts Settings",

View File

@@ -118,6 +118,10 @@ erpnext.integrations.refreshPlaidLink = class refreshPlaidLink {
}
plaid_success(token, response) {
frappe.show_alert({ message: __('Plaid Link Updated'), indicator: 'green' });
frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.update_bank_account_ids', {
response: response,
}).then(() => {
frappe.show_alert({ message: __('Plaid Link Updated'), indicator: 'green' });
});
}
};

View File

@@ -37,14 +37,11 @@ frappe.ui.form.on("Bank Clearance", {
refresh: function(frm) {
frm.disable_save();
frm.add_custom_button(__('Get Payment Entries'), () =>
frm.trigger("get_payment_entries")
);
if (frm.doc.account && frm.doc.from_date && frm.doc.to_date) {
frm.add_custom_button(__('Get Payment Entries'), () =>
frm.trigger("get_payment_entries")
);
frm.change_custom_button_type('Get Payment Entries', null, 'primary');
}
frm.change_custom_button_type(__('Get Payment Entries'), null, 'primary');
},
update_clearance_date: function(frm) {
@@ -56,8 +53,8 @@ frappe.ui.form.on("Bank Clearance", {
frm.refresh_fields();
if (!frm.doc.payment_entries.length) {
frm.change_custom_button_type('Get Payment Entries', null, 'primary');
frm.change_custom_button_type('Update Clearance Date', null, 'default');
frm.change_custom_button_type(__('Get Payment Entries'), null, 'primary');
frm.change_custom_button_type(__('Update Clearance Date'), null, 'default');
}
}
});
@@ -75,8 +72,8 @@ frappe.ui.form.on("Bank Clearance", {
frm.trigger("update_clearance_date")
);
frm.change_custom_button_type('Get Payment Entries', null, 'default');
frm.change_custom_button_type('Update Clearance Date', null, 'primary');
frm.change_custom_button_type(__('Get Payment Entries'), null, 'default');
frm.change_custom_button_type(__('Update Clearance Date'), null, 'primary');
}
}
});

View File

@@ -56,7 +56,7 @@ class BankClearance(Document):
select
"Payment Entry" as payment_document, name as payment_entry,
reference_no as cheque_number, reference_date as cheque_date,
if(paid_from=%(account)s, paid_amount, 0) as credit,
if(paid_from=%(account)s, paid_amount + total_taxes_and_charges, 0) as credit,
if(paid_from=%(account)s, 0, received_amount) as debit,
posting_date, ifnull(party,if(paid_from=%(account)s,paid_to,paid_from)) as against_account, clearance_date,
if(paid_to=%(account)s, paid_to_account_currency, paid_from_account_currency) as account_currency
@@ -81,7 +81,7 @@ class BankClearance(Document):
loan_disbursement = frappe.qb.DocType("Loan Disbursement")
loan_disbursements = (
query = (
frappe.qb.from_(loan_disbursement)
.select(
ConstantColumn("Loan Disbursement").as_("payment_document"),
@@ -90,17 +90,22 @@ class BankClearance(Document):
ConstantColumn(0).as_("debit"),
loan_disbursement.reference_number.as_("cheque_number"),
loan_disbursement.reference_date.as_("cheque_date"),
loan_disbursement.clearance_date.as_("clearance_date"),
loan_disbursement.disbursement_date.as_("posting_date"),
loan_disbursement.applicant.as_("against_account"),
)
.where(loan_disbursement.docstatus == 1)
.where(loan_disbursement.disbursement_date >= self.from_date)
.where(loan_disbursement.disbursement_date <= self.to_date)
.where(loan_disbursement.clearance_date.isnull())
.where(loan_disbursement.disbursement_account.isin([self.bank_account, self.account]))
.orderby(loan_disbursement.disbursement_date)
.orderby(loan_disbursement.name, order=frappe.qb.desc)
).run(as_dict=1)
)
if not self.include_reconciled_entries:
query = query.where(loan_disbursement.clearance_date.isnull())
loan_disbursements = query.run(as_dict=1)
loan_repayment = frappe.qb.DocType("Loan Repayment")
@@ -113,16 +118,19 @@ class BankClearance(Document):
ConstantColumn(0).as_("credit"),
loan_repayment.reference_number.as_("cheque_number"),
loan_repayment.reference_date.as_("cheque_date"),
loan_repayment.clearance_date.as_("clearance_date"),
loan_repayment.applicant.as_("against_account"),
loan_repayment.posting_date,
)
.where(loan_repayment.docstatus == 1)
.where(loan_repayment.clearance_date.isnull())
.where(loan_repayment.posting_date >= self.from_date)
.where(loan_repayment.posting_date <= self.to_date)
.where(loan_repayment.payment_account.isin([self.bank_account, self.account]))
)
if not self.include_reconciled_entries:
query = query.where(loan_repayment.clearance_date.isnull())
if frappe.db.has_column("Loan Repayment", "repay_from_salary"):
query = query.where((loan_repayment.repay_from_salary == 0))

View File

@@ -18,16 +18,30 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
},
onload: function (frm) {
// Set default filter dates
today = frappe.datetime.get_today()
frm.doc.bank_statement_from_date = frappe.datetime.add_months(today, -1);
frm.doc.bank_statement_to_date = today;
frm.trigger('bank_account');
},
filter_by_reference_date: function (frm) {
if (frm.doc.filter_by_reference_date) {
frm.set_value("bank_statement_from_date", "");
frm.set_value("bank_statement_to_date", "");
} else {
frm.set_value("from_reference_date", "");
frm.set_value("to_reference_date", "");
}
},
refresh: function (frm) {
frm.disable_save();
frappe.require("bank-reconciliation-tool.bundle.js", () =>
frm.trigger("make_reconciliation_tool")
);
frm.upload_statement_button = frm.page.set_secondary_action(
__("Upload Bank Statement"),
() =>
frm.add_custom_button(__("Upload Bank Statement"), () =>
frappe.call({
method:
"erpnext.accounts.doctype.bank_statement_import.bank_statement_import.upload_bank_statement",
@@ -49,10 +63,26 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
},
})
);
},
after_save: function (frm) {
frm.trigger("make_reconciliation_tool");
frm.add_custom_button(__('Auto Reconcile'), function() {
frappe.call({
method: "erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.auto_reconcile_vouchers",
args: {
bank_account: frm.doc.bank_account,
from_date: frm.doc.bank_statement_from_date,
to_date: frm.doc.bank_statement_to_date,
filter_by_reference_date: frm.doc.filter_by_reference_date,
from_reference_date: frm.doc.from_reference_date,
to_reference_date: frm.doc.to_reference_date,
},
})
});
frm.add_custom_button(__('Get Unreconciled Entries'), function() {
frm.trigger("make_reconciliation_tool");
});
frm.change_custom_button_type(__('Get Unreconciled Entries'), null, 'primary');
},
bank_account: function (frm) {
@@ -66,7 +96,7 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
r.account,
"account_currency",
(r) => {
frm.currency = r.account_currency;
frm.doc.account_currency = r.account_currency;
frm.trigger("render_chart");
}
);
@@ -132,19 +162,19 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
}
},
render_chart: frappe.utils.debounce((frm) => {
render_chart(frm) {
frm.cards_manager = new erpnext.accounts.bank_reconciliation.NumberCardManager(
{
$reconciliation_tool_cards: frm.get_field(
"reconciliation_tool_cards"
).$wrapper,
bank_statement_closing_balance:
frm.doc.bank_statement_closing_balance,
frm.doc.bank_statement_closing_balance,
cleared_balance: frm.cleared_balance,
currency: frm.currency,
currency: frm.doc.account_currency,
}
);
}, 500),
},
render(frm) {
if (frm.doc.bank_account) {
@@ -160,6 +190,9 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
).$wrapper,
bank_statement_from_date: frm.doc.bank_statement_from_date,
bank_statement_to_date: frm.doc.bank_statement_to_date,
filter_by_reference_date: frm.doc.filter_by_reference_date,
from_reference_date: frm.doc.from_reference_date,
to_reference_date: frm.doc.to_reference_date,
bank_statement_closing_balance:
frm.doc.bank_statement_closing_balance,
cards_manager: frm.cards_manager,

View File

@@ -10,7 +10,11 @@
"column_break_1",
"bank_statement_from_date",
"bank_statement_to_date",
"from_reference_date",
"to_reference_date",
"filter_by_reference_date",
"column_break_2",
"account_currency",
"account_opening_balance",
"bank_statement_closing_balance",
"section_break_1",
@@ -36,13 +40,13 @@
"fieldtype": "Column Break"
},
{
"depends_on": "eval: doc.bank_account",
"depends_on": "eval: doc.bank_account && !doc.filter_by_reference_date",
"fieldname": "bank_statement_from_date",
"fieldtype": "Date",
"label": "From Date"
},
{
"depends_on": "eval: doc.bank_statement_from_date",
"depends_on": "eval: doc.bank_account && !doc.filter_by_reference_date",
"fieldname": "bank_statement_to_date",
"fieldtype": "Date",
"label": "To Date"
@@ -56,7 +60,7 @@
"fieldname": "account_opening_balance",
"fieldtype": "Currency",
"label": "Account Opening Balance",
"options": "Currency",
"options": "account_currency",
"read_only": 1
},
{
@@ -64,7 +68,7 @@
"fieldname": "bank_statement_closing_balance",
"fieldtype": "Currency",
"label": "Closing Balance",
"options": "Currency"
"options": "account_currency"
},
{
"fieldname": "section_break_1",
@@ -81,14 +85,40 @@
},
{
"fieldname": "no_bank_transactions",
"fieldtype": "HTML"
"fieldtype": "HTML",
"options": "<div class=\"text-muted text-center\">No Matching Bank Transactions Found</div>"
},
{
"depends_on": "eval:doc.filter_by_reference_date",
"fieldname": "from_reference_date",
"fieldtype": "Date",
"label": "From Reference Date"
},
{
"depends_on": "eval:doc.filter_by_reference_date",
"fieldname": "to_reference_date",
"fieldtype": "Date",
"label": "To Reference Date"
},
{
"default": "0",
"fieldname": "filter_by_reference_date",
"fieldtype": "Check",
"label": "Filter by Reference Date"
},
{
"fieldname": "account_currency",
"fieldtype": "Link",
"hidden": 1,
"label": "Account Currency",
"options": "Currency"
}
],
"hide_toolbar": 1,
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2021-04-21 11:13:49.831769",
"modified": "2023-03-07 11:02:24.535714",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Bank Reconciliation Tool",
@@ -107,5 +137,6 @@
],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC"
}
"sort_order": "DESC",
"states": []
}

View File

@@ -8,9 +8,9 @@ import frappe
from frappe import _
from frappe.model.document import Document
from frappe.query_builder.custom import ConstantColumn
from frappe.utils import flt
from frappe.utils import cint, flt
from erpnext.accounts.doctype.bank_transaction.bank_transaction import get_paid_amount
from erpnext.accounts.doctype.bank_transaction.bank_transaction import get_total_allocated_amount
from erpnext.accounts.report.bank_reconciliation_statement.bank_reconciliation_statement import (
get_amounts_not_reflected_in_system,
get_entries,
@@ -28,7 +28,7 @@ def get_bank_transactions(bank_account, from_date=None, to_date=None):
filters = []
filters.append(["bank_account", "=", bank_account])
filters.append(["docstatus", "=", 1])
filters.append(["unallocated_amount", ">", 0])
filters.append(["unallocated_amount", ">", 0.0])
if to_date:
filters.append(["date", "<=", to_date])
if from_date:
@@ -50,6 +50,7 @@ def get_bank_transactions(bank_account, from_date=None, to_date=None):
"party",
],
filters=filters,
order_by="date",
)
return transactions
@@ -57,7 +58,7 @@ def get_bank_transactions(bank_account, from_date=None, to_date=None):
@frappe.whitelist()
def get_account_balance(bank_account, till_date):
# returns account balance till the specified date
account = frappe.get_cached_value("Bank Account", bank_account, "account")
account = frappe.db.get_value("Bank Account", bank_account, "account")
filters = frappe._dict(
{"account": account, "report_date": till_date, "include_pos_transactions": 1}
)
@@ -65,7 +66,7 @@ def get_account_balance(bank_account, till_date):
balance_as_per_system = get_balance_on(filters["account"], filters["report_date"])
total_debit, total_credit = 0, 0
total_debit, total_credit = 0.0, 0.0
for d in data:
total_debit += flt(d.debit)
total_credit += flt(d.credit)
@@ -130,10 +131,8 @@ def create_journal_entry_bts(
fieldname=["name", "deposit", "withdrawal", "bank_account"],
as_dict=True,
)[0]
company_account = frappe.get_cached_value(
"Bank Account", bank_transaction.bank_account, "account"
)
account_type = frappe.get_cached_value("Account", second_account, "account_type")
company_account = frappe.get_value("Bank Account", bank_transaction.bank_account, "account")
account_type = frappe.db.get_value("Account", second_account, "account_type")
if account_type in ["Receivable", "Payable"]:
if not (party_type and party):
frappe.throw(
@@ -146,10 +145,8 @@ def create_journal_entry_bts(
accounts.append(
{
"account": second_account,
"credit_in_account_currency": bank_transaction.deposit if bank_transaction.deposit > 0 else 0,
"debit_in_account_currency": bank_transaction.withdrawal
if bank_transaction.withdrawal > 0
else 0,
"credit_in_account_currency": bank_transaction.deposit,
"debit_in_account_currency": bank_transaction.withdrawal,
"party_type": party_type,
"party": party,
}
@@ -159,14 +156,12 @@ def create_journal_entry_bts(
{
"account": company_account,
"bank_account": bank_transaction.bank_account,
"credit_in_account_currency": bank_transaction.withdrawal
if bank_transaction.withdrawal > 0
else 0,
"debit_in_account_currency": bank_transaction.deposit if bank_transaction.deposit > 0 else 0,
"credit_in_account_currency": bank_transaction.withdrawal,
"debit_in_account_currency": bank_transaction.deposit,
}
)
company = frappe.get_cached_value("Account", company_account, "company")
company = frappe.get_value("Account", company_account, "company")
journal_entry_dict = {
"voucher_type": entry_type,
@@ -186,16 +181,22 @@ def create_journal_entry_bts(
journal_entry.insert()
journal_entry.submit()
if bank_transaction.deposit > 0:
if bank_transaction.deposit > 0.0:
paid_amount = bank_transaction.deposit
else:
paid_amount = bank_transaction.withdrawal
vouchers = json.dumps(
[{"payment_doctype": "Journal Entry", "payment_name": journal_entry.name, "amount": paid_amount}]
[
{
"payment_doctype": "Journal Entry",
"payment_name": journal_entry.name,
"amount": paid_amount,
}
]
)
return reconcile_vouchers(bank_transaction.name, vouchers)
return reconcile_vouchers(bank_transaction_name, vouchers)
@frappe.whitelist()
@@ -219,12 +220,10 @@ def create_payment_entry_bts(
as_dict=True,
)[0]
paid_amount = bank_transaction.unallocated_amount
payment_type = "Receive" if bank_transaction.deposit > 0 else "Pay"
payment_type = "Receive" if bank_transaction.deposit > 0.0 else "Pay"
company_account = frappe.get_cached_value(
"Bank Account", bank_transaction.bank_account, "account"
)
company = frappe.get_cached_value("Account", company_account, "company")
company_account = frappe.get_value("Bank Account", bank_transaction.bank_account, "account")
company = frappe.get_value("Account", company_account, "company")
payment_entry_dict = {
"company": company,
"payment_type": payment_type,
@@ -260,9 +259,89 @@ def create_payment_entry_bts(
payment_entry.submit()
vouchers = json.dumps(
[{"payment_doctype": "Payment Entry", "payment_name": payment_entry.name, "amount": paid_amount}]
[
{
"payment_doctype": "Payment Entry",
"payment_name": payment_entry.name,
"amount": paid_amount,
}
]
)
return reconcile_vouchers(bank_transaction.name, vouchers)
return reconcile_vouchers(bank_transaction_name, vouchers)
@frappe.whitelist()
def auto_reconcile_vouchers(
bank_account,
from_date=None,
to_date=None,
filter_by_reference_date=None,
from_reference_date=None,
to_reference_date=None,
):
frappe.flags.auto_reconcile_vouchers = True
document_types = ["payment_entry", "journal_entry"]
bank_transactions = get_bank_transactions(bank_account)
matched_transaction = []
for transaction in bank_transactions:
linked_payments = get_linked_payments(
transaction.name,
document_types,
from_date,
to_date,
filter_by_reference_date,
from_reference_date,
to_reference_date,
)
vouchers = []
for r in linked_payments:
vouchers.append(
{
"payment_doctype": r[1],
"payment_name": r[2],
"amount": r[4],
}
)
transaction = frappe.get_doc("Bank Transaction", transaction.name)
account = frappe.db.get_value("Bank Account", transaction.bank_account, "account")
matched_trans = 0
for voucher in vouchers:
gl_entry = frappe.db.get_value(
"GL Entry",
dict(
account=account, voucher_type=voucher["payment_doctype"], voucher_no=voucher["payment_name"]
),
["credit", "debit"],
as_dict=1,
)
gl_amount, transaction_amount = (
(gl_entry.credit, transaction.deposit)
if gl_entry.credit > 0
else (gl_entry.debit, transaction.withdrawal)
)
allocated_amount = gl_amount if gl_amount >= transaction_amount else transaction_amount
transaction.append(
"payment_entries",
{
"payment_document": voucher["payment_doctype"],
"payment_entry": voucher["payment_name"],
"allocated_amount": allocated_amount,
},
)
matched_transaction.append(str(transaction.name))
transaction.save()
transaction.update_allocations()
matched_transaction_len = len(set(matched_transaction))
if matched_transaction_len == 0:
frappe.msgprint(_("No matching references found for auto reconciliation"))
elif matched_transaction_len == 1:
frappe.msgprint(_("{0} transaction is reconcilied").format(matched_transaction_len))
else:
frappe.msgprint(_("{0} transactions are reconcilied").format(matched_transaction_len))
frappe.flags.auto_reconcile_vouchers = False
return frappe.get_doc("Bank Transaction", transaction.name)
@frappe.whitelist()
@@ -270,80 +349,88 @@ def reconcile_vouchers(bank_transaction_name, vouchers):
# updated clear date of all the vouchers based on the bank transaction
vouchers = json.loads(vouchers)
transaction = frappe.get_doc("Bank Transaction", bank_transaction_name)
company_account = frappe.get_cached_value("Bank Account", transaction.bank_account, "account")
if transaction.unallocated_amount == 0:
frappe.throw(_("This bank transaction is already fully reconciled"))
total_amount = 0
for voucher in vouchers:
voucher["payment_entry"] = frappe.get_doc(voucher["payment_doctype"], voucher["payment_name"])
total_amount += get_paid_amount(
frappe._dict(
{
"payment_document": voucher["payment_doctype"],
"payment_entry": voucher["payment_name"],
}
),
transaction.currency,
company_account,
)
if total_amount > transaction.unallocated_amount:
frappe.throw(
_(
"The sum total of amounts of all selected vouchers should be less than the unallocated amount of the bank transaction"
)
)
account = frappe.get_cached_value("Bank Account", transaction.bank_account, "account")
for voucher in vouchers:
gl_entry = frappe.db.get_value(
"GL Entry",
dict(
account=account, voucher_type=voucher["payment_doctype"], voucher_no=voucher["payment_name"]
),
["credit", "debit"],
as_dict=1,
)
gl_amount, transaction_amount = (
(gl_entry.credit, transaction.deposit)
if gl_entry.credit > 0
else (gl_entry.debit, transaction.withdrawal)
)
allocated_amount = gl_amount if gl_amount >= transaction_amount else transaction_amount
transaction.append(
"payment_entries",
{
"payment_document": voucher["payment_entry"].doctype,
"payment_entry": voucher["payment_entry"].name,
"allocated_amount": allocated_amount,
},
)
transaction.save()
transaction.update_allocations()
transaction.add_payment_entries(vouchers)
return frappe.get_doc("Bank Transaction", bank_transaction_name)
@frappe.whitelist()
def get_linked_payments(bank_transaction_name, document_types=None):
def get_linked_payments(
bank_transaction_name,
document_types=None,
from_date=None,
to_date=None,
filter_by_reference_date=None,
from_reference_date=None,
to_reference_date=None,
):
# get all matching payments for a bank transaction
transaction = frappe.get_doc("Bank Transaction", bank_transaction_name)
bank_account = frappe.db.get_values(
"Bank Account", transaction.bank_account, ["account", "company"], as_dict=True
)[0]
(account, company) = (bank_account.account, bank_account.company)
matching = check_matching(account, company, transaction, document_types)
return matching
(gl_account, company) = (bank_account.account, bank_account.company)
matching = check_matching(
gl_account,
company,
transaction,
document_types,
from_date,
to_date,
filter_by_reference_date,
from_reference_date,
to_reference_date,
)
return subtract_allocations(gl_account, matching)
def check_matching(bank_account, company, transaction, document_types):
def subtract_allocations(gl_account, vouchers):
"Look up & subtract any existing Bank Transaction allocations"
copied = []
for voucher in vouchers:
rows = get_total_allocated_amount(voucher[1], voucher[2])
amount = None
for row in rows:
if row["gl_account"] == gl_account:
amount = row["total"]
break
if amount:
l = list(voucher)
l[3] -= amount
copied.append(tuple(l))
else:
copied.append(voucher)
return copied
def check_matching(
bank_account,
company,
transaction,
document_types,
from_date,
to_date,
filter_by_reference_date,
from_reference_date,
to_reference_date,
):
exact_match = True if "exact_match" in document_types else False
# combine all types of vouchers
subquery = get_queries(bank_account, company, transaction, document_types)
subquery = get_queries(
bank_account,
company,
transaction,
document_types,
from_date,
to_date,
filter_by_reference_date,
from_reference_date,
to_reference_date,
exact_match,
)
filters = {
"amount": transaction.unallocated_amount,
"payment_type": "Receive" if transaction.deposit > 0 else "Pay",
"payment_type": "Receive" if transaction.deposit > 0.0 else "Pay",
"reference_no": transaction.reference_number,
"party_type": transaction.party_type,
"party": transaction.party,
@@ -352,7 +439,9 @@ def check_matching(bank_account, company, transaction, document_types):
matching_vouchers = []
matching_vouchers.extend(get_loan_vouchers(bank_account, transaction, document_types, filters))
matching_vouchers.extend(
get_loan_vouchers(bank_account, transaction, document_types, filters, exact_match)
)
for query in subquery:
matching_vouchers.extend(
@@ -361,14 +450,23 @@ def check_matching(bank_account, company, transaction, document_types):
filters,
)
)
return sorted(matching_vouchers, key=lambda x: x[0], reverse=True) if matching_vouchers else []
def get_queries(bank_account, company, transaction, document_types):
def get_queries(
bank_account,
company,
transaction,
document_types,
from_date,
to_date,
filter_by_reference_date,
from_reference_date,
to_reference_date,
exact_match,
):
# get queries to get matching vouchers
amount_condition = "=" if "exact_match" in document_types else "<="
account_from_to = "paid_to" if transaction.deposit > 0 else "paid_from"
account_from_to = "paid_to" if transaction.deposit > 0.0 else "paid_from"
queries = []
# get matching queries from all the apps
@@ -379,8 +477,13 @@ def get_queries(bank_account, company, transaction, document_types):
company,
transaction,
document_types,
amount_condition,
exact_match,
account_from_to,
from_date,
to_date,
filter_by_reference_date,
from_reference_date,
to_reference_date,
)
or []
)
@@ -389,43 +492,106 @@ def get_queries(bank_account, company, transaction, document_types):
def get_matching_queries(
bank_account, company, transaction, document_types, amount_condition, account_from_to
bank_account,
company,
transaction,
document_types,
exact_match,
account_from_to,
from_date,
to_date,
filter_by_reference_date,
from_reference_date,
to_reference_date,
):
queries = []
if "payment_entry" in document_types:
pe_amount_matching = get_pe_matching_query(amount_condition, account_from_to, transaction)
queries.extend([pe_amount_matching])
query = get_pe_matching_query(
exact_match,
account_from_to,
transaction,
from_date,
to_date,
filter_by_reference_date,
from_reference_date,
to_reference_date,
)
queries.append(query)
if "journal_entry" in document_types:
je_amount_matching = get_je_matching_query(amount_condition, transaction)
queries.extend([je_amount_matching])
query = get_je_matching_query(
exact_match,
transaction,
from_date,
to_date,
filter_by_reference_date,
from_reference_date,
to_reference_date,
)
queries.append(query)
if transaction.deposit > 0 and "sales_invoice" in document_types:
si_amount_matching = get_si_matching_query(amount_condition)
queries.extend([si_amount_matching])
if transaction.deposit > 0.0 and "sales_invoice" in document_types:
query = get_si_matching_query(exact_match)
queries.append(query)
if transaction.withdrawal > 0:
if transaction.withdrawal > 0.0:
if "purchase_invoice" in document_types:
pi_amount_matching = get_pi_matching_query(amount_condition)
queries.extend([pi_amount_matching])
query = get_pi_matching_query(exact_match)
queries.append(query)
if "bank_transaction" in document_types:
query = get_bt_matching_query(exact_match, transaction)
queries.append(query)
return queries
def get_loan_vouchers(bank_account, transaction, document_types, filters):
def get_loan_vouchers(bank_account, transaction, document_types, filters, exact_match):
vouchers = []
amount_condition = True if "exact_match" in document_types else False
if transaction.withdrawal > 0 and "loan_disbursement" in document_types:
vouchers.extend(get_ld_matching_query(bank_account, amount_condition, filters))
if transaction.withdrawal > 0.0 and "loan_disbursement" in document_types:
vouchers.extend(get_ld_matching_query(bank_account, exact_match, filters))
if transaction.deposit > 0 and "loan_repayment" in document_types:
vouchers.extend(get_lr_matching_query(bank_account, amount_condition, filters))
if transaction.deposit > 0.0 and "loan_repayment" in document_types:
vouchers.extend(get_lr_matching_query(bank_account, exact_match, filters))
return vouchers
def get_ld_matching_query(bank_account, amount_condition, filters):
def get_bt_matching_query(exact_match, transaction):
# get matching bank transaction query
# find bank transactions in the same bank account with opposite sign
# same bank account must have same company and currency
field = "deposit" if transaction.withdrawal > 0.0 else "withdrawal"
return f"""
SELECT
(CASE WHEN reference_number = %(reference_no)s THEN 1 ELSE 0 END
+ CASE WHEN {field} = %(amount)s THEN 1 ELSE 0 END
+ CASE WHEN ( party_type = %(party_type)s AND party = %(party)s ) THEN 1 ELSE 0 END
+ CASE WHEN unallocated_amount = %(amount)s THEN 1 ELSE 0 END
+ 1) AS rank,
'Bank Transaction' AS doctype,
name,
unallocated_amount AS paid_amount,
reference_number AS reference_no,
date AS reference_date,
party,
party_type,
date AS posting_date,
currency
FROM
`tabBank Transaction`
WHERE
status != 'Reconciled'
AND name != '{transaction.name}'
AND bank_account = '{transaction.bank_account}'
AND {field} {'= %(amount)s' if exact_match else '> 0.0'}
"""
def get_ld_matching_query(bank_account, exact_match, filters):
loan_disbursement = frappe.qb.DocType("Loan Disbursement")
matching_reference = loan_disbursement.reference_number == filters.get("reference_number")
matching_party = loan_disbursement.applicant_type == filters.get(
@@ -453,17 +619,17 @@ def get_ld_matching_query(bank_account, amount_condition, filters):
.where(loan_disbursement.disbursement_account == bank_account)
)
if amount_condition:
if exact_match:
query.where(loan_disbursement.disbursed_amount == filters.get("amount"))
else:
query.where(loan_disbursement.disbursed_amount <= filters.get("amount"))
query.where(loan_disbursement.disbursed_amount > 0.0)
vouchers = query.run(as_list=True)
return vouchers
def get_lr_matching_query(bank_account, amount_condition, filters):
def get_lr_matching_query(bank_account, exact_match, filters):
loan_repayment = frappe.qb.DocType("Loan Repayment")
matching_reference = loan_repayment.reference_number == filters.get("reference_number")
matching_party = loan_repayment.applicant_type == filters.get(
@@ -494,88 +660,129 @@ def get_lr_matching_query(bank_account, amount_condition, filters):
if frappe.db.has_column("Loan Repayment", "repay_from_salary"):
query = query.where((loan_repayment.repay_from_salary == 0))
if amount_condition:
if exact_match:
query.where(loan_repayment.amount_paid == filters.get("amount"))
else:
query.where(loan_repayment.amount_paid <= filters.get("amount"))
query.where(loan_repayment.amount_paid > 0.0)
vouchers = query.run()
return vouchers
def get_pe_matching_query(amount_condition, account_from_to, transaction):
def get_pe_matching_query(
exact_match,
account_from_to,
transaction,
from_date,
to_date,
filter_by_reference_date,
from_reference_date,
to_reference_date,
):
# get matching payment entries query
if transaction.deposit > 0:
if transaction.deposit > 0.0:
currency_field = "paid_to_account_currency as currency"
else:
currency_field = "paid_from_account_currency as currency"
filter_by_date = f"AND posting_date between '{from_date}' and '{to_date}'"
order_by = " posting_date"
filter_by_reference_no = ""
if cint(filter_by_reference_date):
filter_by_date = f"AND reference_date between '{from_reference_date}' and '{to_reference_date}'"
order_by = " reference_date"
if frappe.flags.auto_reconcile_vouchers == True:
filter_by_reference_no = f"AND reference_no = '{transaction.reference_number}'"
return f"""
SELECT
(CASE WHEN reference_no=%(reference_no)s THEN 1 ELSE 0 END
+ CASE WHEN (party_type = %(party_type)s AND party = %(party)s ) THEN 1 ELSE 0 END
+ 1 ) AS rank,
'Payment Entry' as doctype,
name,
paid_amount,
reference_no,
reference_date,
party,
party_type,
posting_date,
{currency_field}
FROM
`tabPayment Entry`
WHERE
paid_amount {amount_condition} %(amount)s
AND docstatus = 1
AND payment_type IN (%(payment_type)s, 'Internal Transfer')
AND ifnull(clearance_date, '') = ""
AND {account_from_to} = %(bank_account)s
SELECT
(CASE WHEN reference_no=%(reference_no)s THEN 1 ELSE 0 END
+ CASE WHEN (party_type = %(party_type)s AND party = %(party)s ) THEN 1 ELSE 0 END
+ CASE WHEN paid_amount = %(amount)s THEN 1 ELSE 0 END
+ 1 ) AS rank,
'Payment Entry' as doctype,
name,
paid_amount,
reference_no,
reference_date,
party,
party_type,
posting_date,
{currency_field}
FROM
`tabPayment Entry`
WHERE
docstatus = 1
AND payment_type IN (%(payment_type)s, 'Internal Transfer')
AND ifnull(clearance_date, '') = ""
AND {account_from_to} = %(bank_account)s
AND paid_amount {'= %(amount)s' if exact_match else '> 0.0'}
{filter_by_date}
{filter_by_reference_no}
order by{order_by}
"""
def get_je_matching_query(amount_condition, transaction):
def get_je_matching_query(
exact_match,
transaction,
from_date,
to_date,
filter_by_reference_date,
from_reference_date,
to_reference_date,
):
# get matching journal entry query
# We have mapping at the bank level
# So one bank could have both types of bank accounts like asset and liability
# So cr_or_dr should be judged only on basis of withdrawal and deposit and not account type
cr_or_dr = "credit" if transaction.withdrawal > 0 else "debit"
cr_or_dr = "credit" if transaction.withdrawal > 0.0 else "debit"
filter_by_date = f"AND je.posting_date between '{from_date}' and '{to_date}'"
order_by = " je.posting_date"
filter_by_reference_no = ""
if cint(filter_by_reference_date):
filter_by_date = f"AND je.cheque_date between '{from_reference_date}' and '{to_reference_date}'"
order_by = " je.cheque_date"
if frappe.flags.auto_reconcile_vouchers == True:
filter_by_reference_no = f"AND je.cheque_no = '{transaction.reference_number}'"
return f"""
SELECT
(CASE WHEN je.cheque_no=%(reference_no)s THEN 1 ELSE 0 END
+ CASE WHEN jea.{cr_or_dr}_in_account_currency = %(amount)s THEN 1 ELSE 0 END
+ 1) AS rank ,
'Journal Entry' as doctype,
'Journal Entry' AS doctype,
je.name,
jea.{cr_or_dr}_in_account_currency as paid_amount,
je.cheque_no as reference_no,
je.cheque_date as reference_date,
je.pay_to_recd_from as party,
jea.{cr_or_dr}_in_account_currency AS paid_amount,
je.cheque_no AS reference_no,
je.cheque_date AS reference_date,
je.pay_to_recd_from AS party,
jea.party_type,
je.posting_date,
jea.account_currency as currency
jea.account_currency AS currency
FROM
`tabJournal Entry Account` as jea
`tabJournal Entry Account` AS jea
JOIN
`tabJournal Entry` as je
`tabJournal Entry` AS je
ON
jea.parent = je.name
WHERE
(je.clearance_date is null or je.clearance_date='0000-00-00')
je.docstatus = 1
AND je.voucher_type NOT IN ('Opening Entry')
AND (je.clearance_date IS NULL OR je.clearance_date='0000-00-00')
AND jea.account = %(bank_account)s
AND jea.{cr_or_dr}_in_account_currency {amount_condition} %(amount)s
AND jea.{cr_or_dr}_in_account_currency {'= %(amount)s' if exact_match else '> 0.0'}
AND je.docstatus = 1
{filter_by_date}
{filter_by_reference_no}
order by {order_by}
"""
def get_si_matching_query(amount_condition):
# get matchin sales invoice query
def get_si_matching_query(exact_match):
# get matching sales invoice query
return f"""
SELECT
( CASE WHEN si.customer = %(party)s THEN 1 ELSE 0 END
( CASE WHEN si.customer = %(party)s THEN 1 ELSE 0 END
+ CASE WHEN sip.amount = %(amount)s THEN 1 ELSE 0 END
+ 1 ) AS rank,
'Sales Invoice' as doctype,
si.name,
@@ -593,18 +800,20 @@ def get_si_matching_query(amount_condition):
`tabSales Invoice` as si
ON
sip.parent = si.name
WHERE (sip.clearance_date is null or sip.clearance_date='0000-00-00')
WHERE
si.docstatus = 1
AND (sip.clearance_date is null or sip.clearance_date='0000-00-00')
AND sip.account = %(bank_account)s
AND sip.amount {amount_condition} %(amount)s
AND si.docstatus = 1
AND sip.amount {'= %(amount)s' if exact_match else '> 0.0'}
"""
def get_pi_matching_query(amount_condition):
# get matching purchase invoice query
def get_pi_matching_query(exact_match):
# get matching purchase invoice query when they are also used as payment entries (is_paid)
return f"""
SELECT
( CASE WHEN supplier = %(party)s THEN 1 ELSE 0 END
+ CASE WHEN paid_amount = %(amount)s THEN 1 ELSE 0 END
+ 1 ) AS rank,
'Purchase Invoice' as doctype,
name,
@@ -618,9 +827,9 @@ def get_pi_matching_query(amount_condition):
FROM
`tabPurchase Invoice`
WHERE
paid_amount {amount_condition} %(amount)s
AND docstatus = 1
docstatus = 1
AND is_paid = 1
AND ifnull(clearance_date, '') = ""
AND cash_bank_account = %(bank_account)s
AND cash_bank_account = %(bank_account)s
AND paid_amount {'= %(amount)s' if exact_match else '> 0.0'}
"""

View File

@@ -53,19 +53,20 @@ class BankStatementImport(DataImport):
if "Bank Account" not in json.dumps(preview["columns"]):
frappe.throw(_("Please add the Bank Account column"))
from frappe.utils.background_jobs import is_job_queued
from frappe.utils.background_jobs import is_job_enqueued
from frappe.utils.scheduler import is_scheduler_inactive
if is_scheduler_inactive() and not frappe.flags.in_test:
frappe.throw(_("Scheduler is inactive. Cannot import data."), title=_("Scheduler Inactive"))
if not is_job_queued(self.name):
job_id = f"bank_statement_import::{self.name}"
if not is_job_enqueued(job_id):
enqueue(
start_import,
queue="default",
timeout=6000,
event="data_import",
job_name=self.name,
job_id=job_id,
data_import=self.name,
bank_account=self.bank_account,
import_file_path=self.import_file,

View File

@@ -12,8 +12,13 @@ frappe.ui.form.on("Bank Transaction", {
};
});
},
bank_account: function(frm) {
refresh(frm) {
frm.add_custom_button(__('Unreconcile Transaction'), () => {
frm.call('remove_payment_entries')
.then( () => frm.refresh() );
});
},
bank_account: function (frm) {
set_bank_statement_filter(frm);
},
@@ -34,6 +39,7 @@ frappe.ui.form.on("Bank Transaction", {
"Journal Entry",
"Sales Invoice",
"Purchase Invoice",
"Bank Transaction",
];
}
});
@@ -49,7 +55,7 @@ const update_clearance_date = (frm, cdt, cdn) => {
frappe
.xcall(
"erpnext.accounts.doctype.bank_transaction.bank_transaction.unclear_reference_payment",
{ doctype: cdt, docname: cdn }
{ doctype: cdt, docname: cdn, bt_name: frm.doc.name }
)
.then((e) => {
if (e == "success") {

View File

@@ -20,9 +20,11 @@
"currency",
"section_break_10",
"description",
"section_break_14",
"reference_number",
"column_break_10",
"transaction_id",
"transaction_type",
"section_break_14",
"payment_entries",
"section_break_18",
"allocated_amount",
@@ -190,11 +192,21 @@
"label": "Withdrawal",
"oldfieldname": "credit",
"options": "currency"
},
{
"fieldname": "column_break_10",
"fieldtype": "Column Break"
},
{
"fieldname": "transaction_type",
"fieldtype": "Data",
"label": "Transaction Type",
"length": 50
}
],
"is_submittable": 1,
"links": [],
"modified": "2022-03-21 19:05:04.208222",
"modified": "2022-05-29 18:36:50.475964",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Bank Transaction",
@@ -248,4 +260,4 @@
"states": [],
"title_field": "bank_account",
"track_changes": 1
}
}

View File

@@ -1,9 +1,6 @@
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from functools import reduce
import frappe
from frappe.utils import flt
@@ -18,72 +15,135 @@ class BankTransaction(StatusUpdater):
self.clear_linked_payment_entries()
self.set_status()
_saving_flag = False
# nosemgrep: frappe-semgrep-rules.rules.frappe-modifying-but-not-comitting
def on_update_after_submit(self):
self.update_allocations()
self.clear_linked_payment_entries()
self.set_status(update=True)
"Run on save(). Avoid recursion caused by multiple saves"
if not self._saving_flag:
self._saving_flag = True
self.clear_linked_payment_entries()
self.update_allocations()
self._saving_flag = False
def on_cancel(self):
self.clear_linked_payment_entries(for_cancel=True)
self.set_status(update=True)
def update_allocations(self):
"The doctype does not allow modifications after submission, so write to the db direct"
if self.payment_entries:
allocated_amount = reduce(
lambda x, y: flt(x) + flt(y), [x.allocated_amount for x in self.payment_entries]
)
allocated_amount = sum(p.allocated_amount for p in self.payment_entries)
else:
allocated_amount = 0
allocated_amount = 0.0
if allocated_amount:
frappe.db.set_value(self.doctype, self.name, "allocated_amount", flt(allocated_amount))
frappe.db.set_value(
self.doctype,
self.name,
"unallocated_amount",
abs(flt(self.withdrawal) - flt(self.deposit)) - flt(allocated_amount),
)
amount = abs(flt(self.withdrawal) - flt(self.deposit))
self.db_set("allocated_amount", flt(allocated_amount))
self.db_set("unallocated_amount", amount - flt(allocated_amount))
self.reload()
self.set_status(update=True)
else:
frappe.db.set_value(self.doctype, self.name, "allocated_amount", 0)
frappe.db.set_value(
self.doctype, self.name, "unallocated_amount", abs(flt(self.withdrawal) - flt(self.deposit))
)
def add_payment_entries(self, vouchers):
"Add the vouchers with zero allocation. Save() will perform the allocations and clearance"
if 0.0 >= self.unallocated_amount:
frappe.throw(frappe._("Bank Transaction {0} is already fully reconciled").format(self.name))
amount = self.deposit or self.withdrawal
if amount == self.allocated_amount:
frappe.db.set_value(self.doctype, self.name, "status", "Reconciled")
added = False
for voucher in vouchers:
# Can't add same voucher twice
found = False
for pe in self.payment_entries:
if (
pe.payment_document == voucher["payment_doctype"]
and pe.payment_entry == voucher["payment_name"]
):
found = True
if not found:
pe = {
"payment_document": voucher["payment_doctype"],
"payment_entry": voucher["payment_name"],
"allocated_amount": 0.0, # Temporary
}
child = self.append("payment_entries", pe)
added = True
# runs on_update_after_submit
if added:
self.save()
def allocate_payment_entries(self):
"""Refactored from bank reconciliation tool.
Non-zero allocations must be amended/cleared manually
Get the bank transaction amount (b) and remove as we allocate
For each payment_entry if allocated_amount == 0:
- get the amount already allocated against all transactions (t), need latest date
- get the voucher amount (from gl) (v)
- allocate (a = v - t)
- a = 0: should already be cleared, so clear & remove payment_entry
- 0 < a <= u: allocate a & clear
- 0 < a, a > u: allocate u
- 0 > a: Error: already over-allocated
- clear means: set the latest transaction date as clearance date
"""
gl_bank_account = frappe.db.get_value("Bank Account", self.bank_account, "account")
remaining_amount = self.unallocated_amount
for payment_entry in self.payment_entries:
if payment_entry.allocated_amount == 0.0:
unallocated_amount, should_clear, latest_transaction = get_clearance_details(
self, payment_entry
)
if 0.0 == unallocated_amount:
if should_clear:
latest_transaction.clear_linked_payment_entry(payment_entry)
self.db_delete_payment_entry(payment_entry)
elif remaining_amount <= 0.0:
self.db_delete_payment_entry(payment_entry)
elif 0.0 < unallocated_amount and unallocated_amount <= remaining_amount:
payment_entry.db_set("allocated_amount", unallocated_amount)
remaining_amount -= unallocated_amount
if should_clear:
latest_transaction.clear_linked_payment_entry(payment_entry)
elif 0.0 < unallocated_amount and unallocated_amount > remaining_amount:
payment_entry.db_set("allocated_amount", remaining_amount)
remaining_amount = 0.0
elif 0.0 > unallocated_amount:
self.db_delete_payment_entry(payment_entry)
frappe.throw(frappe._("Voucher {0} is over-allocated by {1}").format(unallocated_amount))
self.reload()
def clear_linked_payment_entries(self, for_cancel=False):
def db_delete_payment_entry(self, payment_entry):
frappe.db.delete("Bank Transaction Payments", {"name": payment_entry.name})
@frappe.whitelist()
def remove_payment_entries(self):
for payment_entry in self.payment_entries:
if payment_entry.payment_document == "Sales Invoice":
self.clear_sales_invoice(payment_entry, for_cancel=for_cancel)
elif payment_entry.payment_document in get_doctypes_for_bank_reconciliation():
self.clear_simple_entry(payment_entry, for_cancel=for_cancel)
self.remove_payment_entry(payment_entry)
# runs on_update_after_submit
self.save()
def clear_simple_entry(self, payment_entry, for_cancel=False):
if payment_entry.payment_document == "Payment Entry":
if (
frappe.db.get_value("Payment Entry", payment_entry.payment_entry, "payment_type")
== "Internal Transfer"
):
if len(get_reconciled_bank_transactions(payment_entry)) < 2:
return
def remove_payment_entry(self, payment_entry):
"Clear payment entry and clearance"
self.clear_linked_payment_entry(payment_entry, for_cancel=True)
self.remove(payment_entry)
clearance_date = self.date if not for_cancel else None
frappe.db.set_value(
payment_entry.payment_document, payment_entry.payment_entry, "clearance_date", clearance_date
)
def clear_linked_payment_entries(self, for_cancel=False):
if for_cancel:
for payment_entry in self.payment_entries:
self.clear_linked_payment_entry(payment_entry, for_cancel)
else:
self.allocate_payment_entries()
def clear_sales_invoice(self, payment_entry, for_cancel=False):
clearance_date = self.date if not for_cancel else None
frappe.db.set_value(
"Sales Invoice Payment",
dict(parenttype=payment_entry.payment_document, parent=payment_entry.payment_entry),
"clearance_date",
clearance_date,
def clear_linked_payment_entry(self, payment_entry, for_cancel=False):
clearance_date = None if for_cancel else self.date
set_voucher_clearance(
payment_entry.payment_document, payment_entry.payment_entry, clearance_date, self
)
@@ -93,38 +153,114 @@ def get_doctypes_for_bank_reconciliation():
return frappe.get_hooks("bank_reconciliation_doctypes")
def get_reconciled_bank_transactions(payment_entry):
reconciled_bank_transactions = frappe.get_all(
"Bank Transaction Payments",
filters={"payment_entry": payment_entry.payment_entry},
fields=["parent"],
def get_clearance_details(transaction, payment_entry):
"""
There should only be one bank gle for a voucher.
Could be none for a Bank Transaction.
But if a JE, could affect two banks.
Should only clear the voucher if all bank gles are allocated.
"""
gl_bank_account = frappe.db.get_value("Bank Account", transaction.bank_account, "account")
gles = get_related_bank_gl_entries(payment_entry.payment_document, payment_entry.payment_entry)
bt_allocations = get_total_allocated_amount(
payment_entry.payment_document, payment_entry.payment_entry
)
return reconciled_bank_transactions
unallocated_amount = min(
transaction.unallocated_amount,
get_paid_amount(payment_entry, transaction.currency, gl_bank_account),
)
unmatched_gles = len(gles)
latest_transaction = transaction
for gle in gles:
if gle["gl_account"] == gl_bank_account:
if gle["amount"] <= 0.0:
frappe.throw(
frappe._("Voucher {0} value is broken: {1}").format(
payment_entry.payment_entry, gle["amount"]
)
)
unmatched_gles -= 1
unallocated_amount = gle["amount"]
for a in bt_allocations:
if a["gl_account"] == gle["gl_account"]:
unallocated_amount = gle["amount"] - a["total"]
if frappe.utils.getdate(transaction.date) < a["latest_date"]:
latest_transaction = frappe.get_doc("Bank Transaction", a["latest_name"])
else:
# Must be a Journal Entry affecting more than one bank
for a in bt_allocations:
if a["gl_account"] == gle["gl_account"] and a["total"] == gle["amount"]:
unmatched_gles -= 1
return unallocated_amount, unmatched_gles == 0, latest_transaction
def get_total_allocated_amount(payment_entry):
return frappe.db.sql(
def get_related_bank_gl_entries(doctype, docname):
# nosemgrep: frappe-semgrep-rules.rules.frappe-using-db-sql
result = frappe.db.sql(
"""
SELECT
SUM(btp.allocated_amount) as allocated_amount,
bt.name
ABS(gle.credit_in_account_currency - gle.debit_in_account_currency) AS amount,
gle.account AS gl_account
FROM
`tabBank Transaction Payments` as btp
`tabGL Entry` gle
LEFT JOIN
`tabBank Transaction` bt ON bt.name=btp.parent
`tabAccount` ac ON ac.name=gle.account
WHERE
btp.payment_document = %s
AND
btp.payment_entry = %s
AND
bt.docstatus = 1""",
(payment_entry.payment_document, payment_entry.payment_entry),
ac.account_type = 'Bank'
AND gle.voucher_type = %(doctype)s
AND gle.voucher_no = %(docname)s
AND is_cancelled = 0
""",
dict(doctype=doctype, docname=docname),
as_dict=True,
)
return result
def get_paid_amount(payment_entry, currency, bank_account):
def get_total_allocated_amount(doctype, docname):
"""
Gets the sum of allocations for a voucher on each bank GL account
along with the latest bank transaction name & date
NOTE: query may also include just saved vouchers/payments but with zero allocated_amount
"""
# nosemgrep: frappe-semgrep-rules.rules.frappe-using-db-sql
result = frappe.db.sql(
"""
SELECT total, latest_name, latest_date, gl_account FROM (
SELECT
ROW_NUMBER() OVER w AS rownum,
SUM(btp.allocated_amount) OVER(PARTITION BY ba.account) AS total,
FIRST_VALUE(bt.name) OVER w AS latest_name,
FIRST_VALUE(bt.date) OVER w AS latest_date,
ba.account AS gl_account
FROM
`tabBank Transaction Payments` btp
LEFT JOIN `tabBank Transaction` bt ON bt.name=btp.parent
LEFT JOIN `tabBank Account` ba ON ba.name=bt.bank_account
WHERE
btp.payment_document = %(doctype)s
AND btp.payment_entry = %(docname)s
AND bt.docstatus = 1
WINDOW w AS (PARTITION BY ba.account ORDER BY bt.date desc)
) temp
WHERE
rownum = 1
""",
dict(doctype=doctype, docname=docname),
as_dict=True,
)
for row in result:
# Why is this *sometimes* a byte string?
if isinstance(row["latest_name"], bytes):
row["latest_name"] = row["latest_name"].decode()
row["latest_date"] = frappe.utils.getdate(row["latest_date"])
return result
def get_paid_amount(payment_entry, currency, gl_bank_account):
if payment_entry.payment_document in ["Payment Entry", "Sales Invoice", "Purchase Invoice"]:
paid_amount_field = "paid_amount"
@@ -137,7 +273,7 @@ def get_paid_amount(payment_entry, currency, bank_account):
)
elif doc.payment_type == "Pay":
paid_amount_field = (
"paid_amount" if doc.paid_to_account_currency == currency else "base_paid_amount"
"paid_amount" if doc.paid_from_account_currency == currency else "base_paid_amount"
)
return frappe.db.get_value(
@@ -145,10 +281,13 @@ def get_paid_amount(payment_entry, currency, bank_account):
)
elif payment_entry.payment_document == "Journal Entry":
return frappe.db.get_value(
"Journal Entry Account",
{"parent": payment_entry.payment_entry, "account": bank_account},
"sum(credit_in_account_currency)",
return abs(
frappe.db.get_value(
"Journal Entry Account",
{"parent": payment_entry.payment_entry, "account": gl_bank_account},
"sum(debit_in_account_currency-credit_in_account_currency)",
)
or 0
)
elif payment_entry.payment_document == "Expense Claim":
@@ -166,6 +305,12 @@ def get_paid_amount(payment_entry, currency, bank_account):
payment_entry.payment_document, payment_entry.payment_entry, "amount_paid"
)
elif payment_entry.payment_document == "Bank Transaction":
dep, wth = frappe.db.get_value(
"Bank Transaction", payment_entry.payment_entry, ("deposit", "withdrawal")
)
return abs(flt(wth) - flt(dep))
else:
frappe.throw(
"Please reconcile {0}: {1} manually".format(
@@ -174,18 +319,55 @@ def get_paid_amount(payment_entry, currency, bank_account):
)
@frappe.whitelist()
def unclear_reference_payment(doctype, docname):
if frappe.db.exists(doctype, docname):
doc = frappe.get_doc(doctype, docname)
if doctype == "Sales Invoice":
frappe.db.set_value(
"Sales Invoice Payment",
dict(parenttype=doc.payment_document, parent=doc.payment_entry),
"clearance_date",
None,
)
else:
frappe.db.set_value(doc.payment_document, doc.payment_entry, "clearance_date", None)
def set_voucher_clearance(doctype, docname, clearance_date, self):
if doctype in [
"Payment Entry",
"Journal Entry",
"Purchase Invoice",
"Expense Claim",
"Loan Repayment",
"Loan Disbursement",
]:
if (
doctype == "Payment Entry"
and frappe.db.get_value("Payment Entry", docname, "payment_type") == "Internal Transfer"
and len(get_reconciled_bank_transactions(doctype, docname)) < 2
):
return
frappe.db.set_value(doctype, docname, "clearance_date", clearance_date)
return doc.payment_entry
elif doctype == "Sales Invoice":
frappe.db.set_value(
"Sales Invoice Payment",
dict(parenttype=doctype, parent=docname),
"clearance_date",
clearance_date,
)
elif doctype == "Bank Transaction":
# For when a second bank transaction has fixed another, e.g. refund
bt = frappe.get_doc(doctype, docname)
if clearance_date:
vouchers = [{"payment_doctype": "Bank Transaction", "payment_name": self.name}]
bt.add_payment_entries(vouchers)
else:
for pe in bt.payment_entries:
if pe.payment_document == self.doctype and pe.payment_entry == self.name:
bt.remove(pe)
bt.save()
break
def get_reconciled_bank_transactions(doctype, docname):
return frappe.get_all(
"Bank Transaction Payments",
filters={"payment_document": doctype, "payment_entry": docname},
pluck="parent",
)
@frappe.whitelist()
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

View File

@@ -5,6 +5,7 @@ import json
import unittest
import frappe
from frappe import utils
from frappe.tests.utils import FrappeTestCase
from erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool import (
@@ -40,7 +41,12 @@ class TestBankTransaction(FrappeTestCase):
"Bank Transaction",
dict(description="Re 95282925234 FE/000002917 AT171513000281183046 Conrad Electronic"),
)
linked_payments = get_linked_payments(bank_transaction.name, ["payment_entry", "exact_match"])
linked_payments = get_linked_payments(
bank_transaction.name,
["payment_entry", "exact_match"],
from_date=bank_transaction.date,
to_date=utils.today(),
)
self.assertTrue(linked_payments[0][6] == "Conrad Electronic")
# This test validates a simple reconciliation leading to the clearance of the bank transaction and the payment
@@ -81,7 +87,12 @@ class TestBankTransaction(FrappeTestCase):
"Bank Transaction",
dict(description="Auszahlung Karte MC/000002916 AUTOMAT 698769 K002 27.10. 14:07"),
)
linked_payments = get_linked_payments(bank_transaction.name, ["payment_entry", "exact_match"])
linked_payments = get_linked_payments(
bank_transaction.name,
["payment_entry", "exact_match"],
from_date=bank_transaction.date,
to_date=utils.today(),
)
self.assertTrue(linked_payments[0][3])
# Check error if already reconciled

View File

@@ -125,14 +125,27 @@ def validate_expense_against_budget(args, expense_amount=0):
if not args.account:
return
for budget_against in ["project", "cost_center"] + get_accounting_dimensions():
default_dimensions = [
{
"fieldname": "project",
"document_type": "Project",
},
{
"fieldname": "cost_center",
"document_type": "Cost Center",
},
]
for dimension in default_dimensions + get_accounting_dimensions(as_list=False):
budget_against = dimension.get("fieldname")
if (
args.get(budget_against)
and args.account
and frappe.db.get_value("Account", {"name": args.account, "root_type": "Expense"})
):
doctype = frappe.unscrub(budget_against)
doctype = dimension.get("document_type")
if frappe.get_cached_value("DocType", doctype, "is_tree"):
lft, rgt = frappe.db.get_value(doctype, args.get(budget_against), ["lft", "rgt"])
@@ -184,6 +197,11 @@ def validate_budget_records(args, budget_records, expense_amount):
amount = expense_amount or get_amount(args, budget)
yearly_action, monthly_action = get_actions(args, budget)
if yearly_action in ("Stop", "Warn"):
compare_expense_with_budget(
args, flt(budget.budget_amount), _("Annual"), yearly_action, budget.budget_against, amount
)
if monthly_action in ["Stop", "Warn"]:
budget_amount = get_accumulated_monthly_budget(
budget.monthly_distribution, args.posting_date, args.fiscal_year, budget.budget_amount
@@ -195,28 +213,28 @@ def validate_budget_records(args, budget_records, expense_amount):
args, budget_amount, _("Accumulated Monthly"), monthly_action, budget.budget_against, amount
)
if (
yearly_action in ("Stop", "Warn")
and monthly_action != "Stop"
and yearly_action != monthly_action
):
compare_expense_with_budget(
args, flt(budget.budget_amount), _("Annual"), yearly_action, budget.budget_against, amount
)
def compare_expense_with_budget(args, budget_amount, action_for, action, budget_against, amount=0):
actual_expense = amount or get_actual_expense(args)
if actual_expense > budget_amount:
diff = actual_expense - budget_amount
actual_expense = get_actual_expense(args)
total_expense = actual_expense + amount
if total_expense > budget_amount:
if actual_expense > budget_amount:
error_tense = _("is already")
diff = actual_expense - budget_amount
else:
error_tense = _("will be")
diff = total_expense - budget_amount
currency = frappe.get_cached_value("Company", args.company, "default_currency")
msg = _("{0} Budget for Account {1} against {2} {3} is {4}. It will exceed by {5}").format(
msg = _("{0} Budget for Account {1} against {2} {3} is {4}. It {5} exceed by {6}").format(
_(action_for),
frappe.bold(args.account),
args.budget_against_field,
frappe.unscrub(args.budget_against_field),
frappe.bold(budget_against),
frappe.bold(fmt_money(budget_amount, currency=currency)),
error_tense,
frappe.bold(fmt_money(diff, currency=currency)),
)
@@ -227,9 +245,9 @@ def compare_expense_with_budget(args, budget_amount, action_for, action, budget_
action = "Warn"
if action == "Stop":
frappe.throw(msg, BudgetError)
frappe.throw(msg, BudgetError, title=_("Budget Exceeded"))
else:
frappe.msgprint(msg, indicator="orange")
frappe.msgprint(msg, indicator="orange", title=_("Budget Exceeded"))
def get_actions(args, budget):
@@ -351,7 +369,9 @@ def get_actual_expense(args):
"""
select sum(gle.debit) - sum(gle.credit)
from `tabGL Entry` gle
where gle.account=%(account)s
where
is_cancelled = 0
and gle.account=%(account)s
{condition1}
and gle.fiscal_year=%(fiscal_year)s
and gle.company=%(company)s

View File

@@ -1,6 +0,0 @@
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.ui.form.on('Cash Flow Mapper', {
});

View File

@@ -1,275 +0,0 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 1,
"autoname": "field:section_name",
"beta": 0,
"creation": "2018-02-08 10:00:14.066519",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Section Name",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_header",
"fieldtype": "Data",
"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": "Section Header",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "e.g Adjustments for:",
"fieldname": "section_leader",
"fieldtype": "Data",
"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": "Section Leader",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_subtotal",
"fieldtype": "Data",
"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": "Section Subtotal",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_footer",
"fieldtype": "Data",
"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": "Section Footer",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "accounts",
"fieldtype": "Table",
"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": "Accounts",
"length": 0,
"no_copy": 0,
"options": "Cash Flow Mapping Template Details",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "position",
"fieldtype": "Int",
"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": "Position",
"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,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-02-15 18:28:55.034933",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Cash Flow Mapper",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"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": 0,
"write": 1
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "name",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0
}

View File

@@ -1,9 +0,0 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from frappe.model.document import Document
class CashFlowMapper(Document):
pass

View File

@@ -1,25 +0,0 @@
DEFAULT_MAPPERS = [
{
"doctype": "Cash Flow Mapper",
"section_footer": "Net cash generated by operating activities",
"section_header": "Cash flows from operating activities",
"section_leader": "Adjustments for",
"section_name": "Operating Activities",
"position": 0,
"section_subtotal": "Cash generated from operations",
},
{
"doctype": "Cash Flow Mapper",
"position": 1,
"section_footer": "Net cash used in investing activities",
"section_header": "Cash flows from investing activities",
"section_name": "Investing Activities",
},
{
"doctype": "Cash Flow Mapper",
"position": 2,
"section_footer": "Net cash used in financing activites",
"section_header": "Cash flows from financing activities",
"section_name": "Financing Activities",
},
]

View File

@@ -1,8 +0,0 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
class TestCashFlowMapper(unittest.TestCase):
pass

View File

@@ -1,43 +0,0 @@
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.ui.form.on('Cash Flow Mapping', {
refresh: function(frm) {
frm.events.disable_unchecked_fields(frm);
},
reset_check_fields: function(frm) {
frm.fields.filter(field => field.df.fieldtype === 'Check')
.map(field => frm.set_df_property(field.df.fieldname, 'read_only', 0));
},
has_checked_field(frm) {
const val = frm.fields.filter(field => field.value === 1);
return val.length ? 1 : 0;
},
_disable_unchecked_fields: function(frm) {
// get value of clicked field
frm.fields.filter(field => field.value === 0)
.map(field => frm.set_df_property(field.df.fieldname, 'read_only', 1));
},
disable_unchecked_fields: function(frm) {
frm.events.reset_check_fields(frm);
const checked = frm.events.has_checked_field(frm);
if (checked) {
frm.events._disable_unchecked_fields(frm);
}
},
is_working_capital: function(frm) {
frm.events.disable_unchecked_fields(frm);
},
is_finance_cost: function(frm) {
frm.events.disable_unchecked_fields(frm);
},
is_income_tax_liability: function(frm) {
frm.events.disable_unchecked_fields(frm);
},
is_income_tax_expense: function(frm) {
frm.events.disable_unchecked_fields(frm);
},
is_finance_cost_adjustment: function(frm) {
frm.events.disable_unchecked_fields(frm);
}
});

View File

@@ -1,359 +0,0 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 1,
"autoname": "field:mapping_name",
"beta": 0,
"creation": "2018-02-08 09:28:44.678364",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "mapping_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Name",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "label",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Label",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "accounts",
"fieldtype": "Table",
"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": "Accounts",
"length": 0,
"no_copy": 0,
"options": "Cash Flow Mapping Accounts",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "sb_1",
"fieldtype": "Section Break",
"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": "Select Maximum Of 1",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"fieldname": "is_finance_cost",
"fieldtype": "Check",
"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": "Is Finance Cost",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"fieldname": "is_working_capital",
"fieldtype": "Check",
"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": "Is Working Capital",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"fieldname": "is_finance_cost_adjustment",
"fieldtype": "Check",
"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": "Is Finance Cost Adjustment",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"fieldname": "is_income_tax_liability",
"fieldtype": "Check",
"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": "Is Income Tax Liability",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"fieldname": "is_income_tax_expense",
"fieldtype": "Check",
"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": "Is Income Tax 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,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-02-15 08:25:18.693533",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Cash Flow Mapping",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 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": 0,
"write": 1
},
{
"amend": 0,
"apply_user_permissions": 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": "Administrator",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "name",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0
}

View File

@@ -1,22 +0,0 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
import frappe
from frappe import _
from frappe.model.document import Document
class CashFlowMapping(Document):
def validate(self):
self.validate_checked_options()
def validate_checked_options(self):
checked_fields = [
d for d in self.meta.fields if d.fieldtype == "Check" and self.get(d.fieldname) == 1
]
if len(checked_fields) > 1:
frappe.throw(
_("You can only select a maximum of one option from the list of check boxes."),
title=_("Error"),
)

View File

@@ -1,28 +0,0 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
class TestCashFlowMapping(unittest.TestCase):
def setUp(self):
if frappe.db.exists("Cash Flow Mapping", "Test Mapping"):
frappe.delete_doc("Cash Flow Mappping", "Test Mapping")
def tearDown(self):
frappe.delete_doc("Cash Flow Mapping", "Test Mapping")
def test_multiple_selections_not_allowed(self):
doc = frappe.new_doc("Cash Flow Mapping")
doc.mapping_name = "Test Mapping"
doc.label = "Test label"
doc.append("accounts", {"account": "Accounts Receivable - _TC"})
doc.is_working_capital = 1
doc.is_finance_cost = 1
self.assertRaises(frappe.ValidationError, doc.insert)
doc.is_finance_cost = 0
doc.insert()

View File

@@ -1,73 +0,0 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "field:account",
"beta": 0,
"creation": "2018-02-08 09:25:34.353995",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "account",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "account",
"length": 0,
"no_copy": 0,
"options": "Account",
"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,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2018-02-08 09:25:34.353995",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Cash Flow Mapping Accounts",
"name_case": "",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"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
}

View File

@@ -1,9 +0,0 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from frappe.model.document import Document
class CashFlowMappingAccounts(Document):
pass

View File

@@ -1,6 +0,0 @@
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.ui.form.on('Cash Flow Mapping Template', {
});

View File

@@ -1,123 +0,0 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2018-02-08 10:20:18.316801",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "template_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Template Name",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "mapping",
"fieldtype": "Table",
"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": "Cash Flow Mapping",
"length": 0,
"no_copy": 0,
"options": "Cash Flow Mapping Template Details",
"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,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-02-08 10:20:18.316801",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Cash Flow Mapping Template",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 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": 0,
"write": 1
}
],
"quick_entry": 1,
"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
}

View File

@@ -1,9 +0,0 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from frappe.model.document import Document
class CashFlowMappingTemplate(Document):
pass

View File

@@ -1,8 +0,0 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
class TestCashFlowMappingTemplate(unittest.TestCase):
pass

View File

@@ -1,6 +0,0 @@
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.ui.form.on('Cash Flow Mapping Template Details', {
});

View File

@@ -1,34 +0,0 @@
{
"actions": [],
"creation": "2018-02-08 10:18:48.513608",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"mapping"
],
"fields": [
{
"fieldname": "mapping",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Mapping",
"options": "Cash Flow Mapping",
"reqd": 1,
"unique": 1
}
],
"istable": 1,
"links": [],
"modified": "2022-02-21 03:34:57.902332",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Cash Flow Mapping Template Details",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -1,9 +0,0 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from frappe.model.document import Document
class CashFlowMappingTemplateDetails(Document):
pass

View File

@@ -1,8 +0,0 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
class TestCashFlowMappingTemplateDetails(unittest.TestCase):
pass

View File

@@ -36,7 +36,7 @@ def validate_columns(data):
no_of_columns = max([len(d) for d in data])
if no_of_columns > 7:
if no_of_columns > 8:
frappe.throw(
_("More columns found than expected. Please compare the uploaded file with standard template"),
title=(_("Wrong Template")),
@@ -233,6 +233,7 @@ def build_forest(data):
is_group,
account_type,
root_type,
account_currency,
) = i
if not account_name:
@@ -253,6 +254,8 @@ def build_forest(data):
charts_map[account_name]["account_type"] = account_type
if root_type:
charts_map[account_name]["root_type"] = root_type
if account_currency:
charts_map[account_name]["account_currency"] = account_currency
path = return_parent(data, account_name)[::-1]
paths.append(path) # List of path is created
line_no += 1
@@ -315,20 +318,21 @@ def get_template(template_type):
"Is Group",
"Account Type",
"Root Type",
"Account Currency",
]
writer = UnicodeWriter()
writer.writerow(fields)
if template_type == "Blank Template":
for root_type in get_root_types():
writer.writerow(["", "", "", 1, "", root_type])
writer.writerow(["", "", "", "", 1, "", root_type])
for account in get_mandatory_group_accounts():
writer.writerow(["", "", "", 1, account, "Asset"])
writer.writerow(["", "", "", "", 1, account, "Asset"])
for account_type in get_mandatory_account_types():
writer.writerow(
["", "", "", 0, account_type.get("account_type"), account_type.get("root_type")]
["", "", "", "", 0, account_type.get("account_type"), account_type.get("root_type")]
)
else:
writer = get_sample_template(writer)
@@ -485,6 +489,10 @@ def set_default_accounts(company):
"default_payable_account": frappe.db.get_value(
"Account", {"company": company.name, "account_type": "Payable", "is_group": 0}
),
"default_provisional_account": frappe.db.get_value(
"Account",
{"company": company.name, "account_type": "Service Received But Not Billed", "is_group": 0},
),
}
)

View File

@@ -28,9 +28,14 @@ class InvalidDateError(frappe.ValidationError):
class CostCenterAllocation(Document):
def __init__(self, *args, **kwargs):
super(CostCenterAllocation, self).__init__(*args, **kwargs)
self._skip_from_date_validation = False
def validate(self):
self.validate_total_allocation_percentage()
self.validate_from_date_based_on_existing_gle()
if not self._skip_from_date_validation:
self.validate_from_date_based_on_existing_gle()
self.validate_backdated_allocation()
self.validate_main_cost_center()
self.validate_child_cost_centers()

View File

@@ -6,6 +6,7 @@
"engine": "InnoDB",
"field_order": [
"api_details_section",
"disabled",
"service_provider",
"api_endpoint",
"url",
@@ -77,12 +78,18 @@
"label": "Service Provider",
"options": "frankfurter.app\nexchangerate.host\nCustom",
"reqd": 1
},
{
"default": "0",
"fieldname": "disabled",
"fieldtype": "Check",
"label": "Disabled"
}
],
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2022-01-10 15:51:14.521174",
"modified": "2023-01-09 12:19:03.955906",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Currency Exchange Settings",

View File

@@ -245,6 +245,7 @@
"fieldname": "contact_mobile",
"fieldtype": "Small Text",
"label": "Mobile No",
"options": "Phone",
"read_only": 1
},
{
@@ -315,10 +316,11 @@
],
"is_submittable": 1,
"links": [],
"modified": "2020-08-03 18:55:43.683053",
"modified": "2023-06-03 16:24:01.677026",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Dunning",
"naming_rule": "By \"Naming Series\" field",
"owner": "Administrator",
"permissions": [
{
@@ -365,6 +367,7 @@
],
"sort_field": "modified",
"sort_order": "ASC",
"states": [],
"title_field": "customer_name",
"track_changes": 1
}

View File

@@ -40,7 +40,7 @@ class Dunning(AccountsController):
def on_cancel(self):
if self.dunning_amount:
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry")
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry", "Payment Ledger Entry")
make_reverse_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
def make_gl_entries(self):

View File

@@ -26,7 +26,7 @@ frappe.ui.form.on('Exchange Rate Revaluation', {
doc: frm.doc,
callback: function(r) {
if (r.message) {
frm.add_custom_button(__('Journal Entry'), function() {
frm.add_custom_button(__('Journal Entries'), function() {
return frm.events.make_jv(frm);
}, __('Create'));
}
@@ -35,10 +35,26 @@ frappe.ui.form.on('Exchange Rate Revaluation', {
}
},
get_entries: function(frm) {
validate_rounding_loss: function(frm) {
allowance = frm.doc.rounding_loss_allowance;
if (!(allowance > 0 && allowance < 1)) {
frappe.throw(__("Rounding Loss Allowance should be between 0 and 1"));
}
},
rounding_loss_allowance: function(frm) {
frm.events.validate_rounding_loss(frm);
},
validate: function(frm) {
frm.events.validate_rounding_loss(frm);
},
get_entries: function(frm, account) {
frappe.call({
method: "get_accounts_data",
doc: cur_frm.doc,
account: account,
callback: function(r){
frappe.model.clear_table(frm.doc, "accounts");
if(r.message) {
@@ -57,7 +73,6 @@ frappe.ui.form.on('Exchange Rate Revaluation', {
let total_gain_loss = 0;
frm.doc.accounts.forEach((d) => {
d.gain_loss = flt(d.new_balance_in_base_currency, precision("new_balance_in_base_currency", d)) - flt(d.balance_in_base_currency, precision("balance_in_base_currency", d));
total_gain_loss += flt(d.gain_loss, precision("gain_loss", d));
});
@@ -66,13 +81,19 @@ frappe.ui.form.on('Exchange Rate Revaluation', {
},
make_jv : function(frm) {
let revaluation_journal = null;
let zero_balance_journal = null;
frappe.call({
method: "make_jv_entry",
method: "make_jv_entries",
doc: frm.doc,
freeze: true,
freeze_message: "Making Journal Entries...",
callback: function(r){
if (r.message) {
var doc = frappe.model.sync(r.message)[0];
frappe.set_route("Form", doc.doctype, doc.name);
let response = r.message;
if(response['revaluation_jv'] || response['zero_balance_jv']) {
frappe.msgprint(__("Journals have been created"));
}
}
}
});
@@ -120,7 +141,8 @@ var get_account_details = function(frm, cdt, cdn) {
company: frm.doc.company,
posting_date: frm.doc.posting_date,
party_type: row.party_type,
party: row.party
party: row.party,
rounding_loss_allowance: frm.doc.rounding_loss_allowance
},
callback: function(r){
$.extend(row, r.message);

View File

@@ -8,12 +8,16 @@
"engine": "InnoDB",
"field_order": [
"posting_date",
"rounding_loss_allowance",
"column_break_2",
"company",
"section_break_4",
"get_entries",
"accounts",
"section_break_6",
"gain_loss_unbooked",
"gain_loss_booked",
"column_break_10",
"total_gain_loss",
"amended_from"
],
@@ -59,13 +63,6 @@
"fieldname": "section_break_6",
"fieldtype": "Section Break"
},
{
"fieldname": "total_gain_loss",
"fieldtype": "Currency",
"label": "Total Gain/Loss",
"options": "Company:company:default_currency",
"read_only": 1
},
{
"fieldname": "amended_from",
"fieldtype": "Link",
@@ -74,11 +71,44 @@
"options": "Exchange Rate Revaluation",
"print_hide": 1,
"read_only": 1
},
{
"fieldname": "gain_loss_unbooked",
"fieldtype": "Currency",
"label": "Gain/Loss from Revaluation",
"options": "Company:company:default_currency",
"read_only": 1
},
{
"description": "Gain/Loss accumulated in foreign currency account. Accounts with '0' balance in either Base or Account currency",
"fieldname": "gain_loss_booked",
"fieldtype": "Currency",
"label": "Gain/Loss already booked",
"options": "Company:company:default_currency",
"read_only": 1
},
{
"fieldname": "total_gain_loss",
"fieldtype": "Currency",
"label": "Total Gain/Loss",
"options": "Company:company:default_currency",
"read_only": 1
},
{
"fieldname": "column_break_10",
"fieldtype": "Column Break"
},
{
"default": "0.05",
"description": "Only values between 0 and 1 are allowed. \nEx: If allowance is set at 0.07, accounts that have balance of 0.07 in either of the currencies will be considered as zero balance account",
"fieldname": "rounding_loss_allowance",
"fieldtype": "Float",
"label": "Rounding Loss Allowance"
}
],
"is_submittable": 1,
"links": [],
"modified": "2022-11-17 10:28:03.911554",
"modified": "2023-06-12 21:02:09.818208",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Exchange Rate Revaluation",

View File

@@ -3,27 +3,49 @@
import frappe
from frappe import _
from frappe import _, qb
from frappe.model.document import Document
from frappe.model.meta import get_field_precision
from frappe.utils import flt
from frappe.query_builder import Criterion, Order
from frappe.query_builder.functions import NullIf, Sum
from frappe.utils import flt, get_link_to_form
import erpnext
from erpnext.accounts.doctype.journal_entry.journal_entry import get_balance_on
from erpnext.accounts.utils import get_currency_precision
from erpnext.setup.utils import get_exchange_rate
class ExchangeRateRevaluation(Document):
def validate(self):
self.validate_rounding_loss_allowance()
self.set_total_gain_loss()
def validate_rounding_loss_allowance(self):
if not (self.rounding_loss_allowance > 0 and self.rounding_loss_allowance < 1):
frappe.throw(_("Rounding Loss Allowance should be between 0 and 1"))
def set_total_gain_loss(self):
total_gain_loss = 0
gain_loss_booked = 0
gain_loss_unbooked = 0
for d in self.accounts:
d.gain_loss = flt(
d.new_balance_in_base_currency, d.precision("new_balance_in_base_currency")
) - flt(d.balance_in_base_currency, d.precision("balance_in_base_currency"))
if not d.zero_balance:
d.gain_loss = flt(
d.new_balance_in_base_currency, d.precision("new_balance_in_base_currency")
) - flt(d.balance_in_base_currency, d.precision("balance_in_base_currency"))
if d.zero_balance:
gain_loss_booked += flt(d.gain_loss, d.precision("gain_loss"))
else:
gain_loss_unbooked += flt(d.gain_loss, d.precision("gain_loss"))
total_gain_loss += flt(d.gain_loss, d.precision("gain_loss"))
self.gain_loss_booked = gain_loss_booked
self.gain_loss_unbooked = gain_loss_unbooked
self.total_gain_loss = flt(total_gain_loss, self.precision("total_gain_loss"))
def validate_mandatory(self):
@@ -35,98 +57,229 @@ class ExchangeRateRevaluation(Document):
@frappe.whitelist()
def check_journal_entry_condition(self):
total_debit = frappe.db.get_value(
"Journal Entry Account",
{"reference_type": "Exchange Rate Revaluation", "reference_name": self.name, "docstatus": 1},
"sum(debit) as sum",
exchange_gain_loss_account = self.get_for_unrealized_gain_loss_account()
jea = qb.DocType("Journal Entry Account")
journals = (
qb.from_(jea)
.select(jea.parent)
.distinct()
.where(
(jea.reference_type == "Exchange Rate Revaluation")
& (jea.reference_name == self.name)
& (jea.docstatus == 1)
)
.run()
)
total_amt = 0
for d in self.accounts:
total_amt = total_amt + d.new_balance_in_base_currency
if journals:
gle = qb.DocType("GL Entry")
total_amt = (
qb.from_(gle)
.select((Sum(gle.credit) - Sum(gle.debit)).as_("total_amount"))
.where(
(gle.voucher_type == "Journal Entry")
& (gle.voucher_no.isin(journals))
& (gle.account == exchange_gain_loss_account)
& (gle.is_cancelled == 0)
)
.run()
)
if total_amt != total_debit:
return True
if total_amt and total_amt[0][0] != self.total_gain_loss:
return True
else:
return False
return False
return True
@frappe.whitelist()
def get_accounts_data(self, account=None):
accounts = []
def get_accounts_data(self):
self.validate_mandatory()
company_currency = erpnext.get_company_currency(self.company)
account_details = self.get_account_balance_from_gle(
company=self.company,
posting_date=self.posting_date,
account=None,
party_type=None,
party=None,
rounding_loss_allowance=self.rounding_loss_allowance,
)
accounts_with_new_balance = self.calculate_new_account_balance(
self.company, self.posting_date, account_details
)
if not accounts_with_new_balance:
self.throw_invalid_response_message(account_details)
return accounts_with_new_balance
@staticmethod
def get_account_balance_from_gle(
company, posting_date, account, party_type, party, rounding_loss_allowance
):
account_details = []
if company and posting_date:
company_currency = erpnext.get_company_currency(company)
acc = qb.DocType("Account")
if account:
accounts = [account]
else:
res = (
qb.from_(acc)
.select(acc.name)
.where(
(acc.is_group == 0)
& (acc.report_type == "Balance Sheet")
& (acc.root_type.isin(["Asset", "Liability", "Equity"]))
& (acc.account_type != "Stock")
& (acc.company == company)
& (acc.account_currency != company_currency)
)
.orderby(acc.name)
.run(as_list=True)
)
accounts = [x[0] for x in res]
if accounts:
having_clause = (qb.Field("balance") != qb.Field("balance_in_account_currency")) & (
(qb.Field("balance_in_account_currency") != 0) | (qb.Field("balance") != 0)
)
gle = qb.DocType("GL Entry")
# conditions
conditions = []
conditions.append(gle.account.isin(accounts))
conditions.append(gle.posting_date.lte(posting_date))
conditions.append(gle.is_cancelled == 0)
if party_type:
conditions.append(gle.party_type == party_type)
if party:
conditions.append(gle.party == party)
account_details = (
qb.from_(gle)
.select(
gle.account,
gle.party_type,
gle.party,
gle.account_currency,
(Sum(gle.debit_in_account_currency) - Sum(gle.credit_in_account_currency)).as_(
"balance_in_account_currency"
),
(Sum(gle.debit) - Sum(gle.credit)).as_("balance"),
(Sum(gle.debit) - Sum(gle.credit) == 0)
^ (Sum(gle.debit_in_account_currency) - Sum(gle.credit_in_account_currency) == 0).as_(
"zero_balance"
),
)
.where(Criterion.all(conditions))
.groupby(gle.account, NullIf(gle.party_type, ""), NullIf(gle.party, ""))
.having(having_clause)
.orderby(gle.account)
.run(as_dict=True)
)
# round off balance based on currency precision
# and consider debit-credit difference allowance
currency_precision = get_currency_precision()
rounding_loss_allowance = rounding_loss_allowance or 0.05
for acc in account_details:
acc.balance_in_account_currency = flt(acc.balance_in_account_currency, currency_precision)
if abs(acc.balance_in_account_currency) <= rounding_loss_allowance:
acc.balance_in_account_currency = 0
acc.balance = flt(acc.balance, currency_precision)
if abs(acc.balance) <= rounding_loss_allowance:
acc.balance = 0
acc.zero_balance = (
True if (acc.balance == 0 or acc.balance_in_account_currency == 0) else False
)
return account_details
@staticmethod
def calculate_new_account_balance(company, posting_date, account_details):
accounts = []
company_currency = erpnext.get_company_currency(company)
precision = get_field_precision(
frappe.get_meta("Exchange Rate Revaluation Account").get_field("new_balance_in_base_currency"),
company_currency,
)
account_details = self.get_accounts_from_gle()
for d in account_details:
current_exchange_rate = (
d.balance / d.balance_in_account_currency if d.balance_in_account_currency else 0
)
new_exchange_rate = get_exchange_rate(d.account_currency, company_currency, self.posting_date)
new_balance_in_base_currency = flt(d.balance_in_account_currency * new_exchange_rate)
gain_loss = flt(new_balance_in_base_currency, precision) - flt(d.balance, precision)
if gain_loss:
accounts.append(
{
"account": d.account,
"party_type": d.party_type,
"party": d.party,
"account_currency": d.account_currency,
"balance_in_base_currency": d.balance,
"balance_in_account_currency": d.balance_in_account_currency,
"current_exchange_rate": current_exchange_rate,
"new_exchange_rate": new_exchange_rate,
"new_balance_in_base_currency": new_balance_in_base_currency,
}
if account_details:
# Handle Accounts with balance in both Account/Base Currency
for d in [x for x in account_details if not x.zero_balance]:
current_exchange_rate = (
d.balance / d.balance_in_account_currency if d.balance_in_account_currency else 0
)
new_exchange_rate = get_exchange_rate(d.account_currency, company_currency, posting_date)
new_balance_in_base_currency = flt(d.balance_in_account_currency * new_exchange_rate)
gain_loss = flt(new_balance_in_base_currency, precision) - flt(d.balance, precision)
if gain_loss:
accounts.append(
{
"account": d.account,
"party_type": d.party_type,
"party": d.party,
"account_currency": d.account_currency,
"balance_in_base_currency": d.balance,
"balance_in_account_currency": d.balance_in_account_currency,
"zero_balance": d.zero_balance,
"current_exchange_rate": current_exchange_rate,
"new_exchange_rate": new_exchange_rate,
"new_balance_in_base_currency": new_balance_in_base_currency,
"new_balance_in_account_currency": d.balance_in_account_currency,
"gain_loss": gain_loss,
}
)
if not accounts:
self.throw_invalid_response_message(account_details)
# Handle Accounts with '0' balance in Account/Base Currency
for d in [x for x in account_details if x.zero_balance]:
if d.balance != 0:
current_exchange_rate = new_exchange_rate = 0
new_balance_in_account_currency = 0 # this will be '0'
new_balance_in_base_currency = 0 # this will be '0'
gain_loss = flt(new_balance_in_base_currency, precision) - flt(d.balance, precision)
else:
new_exchange_rate = 0
new_balance_in_base_currency = 0
new_balance_in_account_currency = 0
current_exchange_rate = calculate_exchange_rate_using_last_gle(
company, d.account, d.party_type, d.party
)
gain_loss = new_balance_in_account_currency - (
current_exchange_rate * d.balance_in_account_currency
)
if gain_loss:
accounts.append(
{
"account": d.account,
"party_type": d.party_type,
"party": d.party,
"account_currency": d.account_currency,
"balance_in_base_currency": d.balance,
"balance_in_account_currency": d.balance_in_account_currency,
"zero_balance": d.zero_balance,
"current_exchange_rate": current_exchange_rate,
"new_exchange_rate": new_exchange_rate,
"new_balance_in_base_currency": new_balance_in_base_currency,
"new_balance_in_account_currency": new_balance_in_account_currency,
"gain_loss": gain_loss,
}
)
return accounts
def get_accounts_from_gle(self):
company_currency = erpnext.get_company_currency(self.company)
accounts = frappe.db.sql_list(
"""
select name
from tabAccount
where is_group = 0
and report_type = 'Balance Sheet'
and root_type in ('Asset', 'Liability', 'Equity')
and account_type != 'Stock'
and company=%s
and account_currency != %s
order by name""",
(self.company, company_currency),
)
account_details = []
if accounts:
account_details = frappe.db.sql(
"""
select
account, party_type, party, account_currency,
sum(debit_in_account_currency) - sum(credit_in_account_currency) as balance_in_account_currency,
sum(debit) - sum(credit) as balance
from `tabGL Entry`
where account in (%s)
and posting_date <= %s
and is_cancelled = 0
group by account, NULLIF(party_type,''), NULLIF(party,'')
having sum(debit) != sum(credit)
order by account
"""
% (", ".join(["%s"] * len(accounts)), "%s"),
tuple(accounts + [self.posting_date]),
as_dict=1,
)
return account_details
def throw_invalid_response_message(self, account_details):
if account_details:
message = _("No outstanding invoices require exchange rate revaluation")
@@ -134,11 +287,7 @@ class ExchangeRateRevaluation(Document):
message = _("No outstanding invoices found")
frappe.msgprint(message)
@frappe.whitelist()
def make_jv_entry(self):
if self.total_gain_loss == 0:
return
def get_for_unrealized_gain_loss_account(self):
unrealized_exchange_gain_loss_account = frappe.get_cached_value(
"Company", self.company, "unrealized_exchange_gain_loss_account"
)
@@ -146,6 +295,130 @@ class ExchangeRateRevaluation(Document):
frappe.throw(
_("Please set Unrealized Exchange Gain/Loss Account in Company {0}").format(self.company)
)
return unrealized_exchange_gain_loss_account
@frappe.whitelist()
def make_jv_entries(self):
zero_balance_jv = self.make_jv_for_zero_balance()
if zero_balance_jv:
frappe.msgprint(
f"Zero Balance Journal: {get_link_to_form('Journal Entry', zero_balance_jv.name)}"
)
revaluation_jv = self.make_jv_for_revaluation()
if revaluation_jv:
frappe.msgprint(
f"Revaluation Journal: {get_link_to_form('Journal Entry', revaluation_jv.name)}"
)
return {
"revaluation_jv": revaluation_jv.name if revaluation_jv else None,
"zero_balance_jv": zero_balance_jv.name if zero_balance_jv else None,
}
def make_jv_for_zero_balance(self):
if self.gain_loss_booked == 0:
return
accounts = [x for x in self.accounts if x.zero_balance]
if not accounts:
return
unrealized_exchange_gain_loss_account = self.get_for_unrealized_gain_loss_account()
journal_entry = frappe.new_doc("Journal Entry")
journal_entry.voucher_type = "Exchange Gain Or Loss"
journal_entry.company = self.company
journal_entry.posting_date = self.posting_date
journal_entry.multi_currency = 1
journal_entry_accounts = []
for d in accounts:
journal_account = frappe._dict(
{
"account": d.get("account"),
"party_type": d.get("party_type"),
"party": d.get("party"),
"account_currency": d.get("account_currency"),
"balance": flt(
d.get("balance_in_account_currency"), d.precision("balance_in_account_currency")
),
"exchange_rate": 0,
"cost_center": erpnext.get_default_cost_center(self.company),
"reference_type": "Exchange Rate Revaluation",
"reference_name": self.name,
}
)
# Account Currency has balance
if d.get("balance_in_account_currency") and not d.get("new_balance_in_account_currency"):
dr_or_cr = (
"credit_in_account_currency"
if d.get("balance_in_account_currency") > 0
else "debit_in_account_currency"
)
reverse_dr_or_cr = (
"debit_in_account_currency"
if dr_or_cr == "credit_in_account_currency"
else "credit_in_account_currency"
)
journal_account.update(
{
dr_or_cr: flt(
abs(d.get("balance_in_account_currency")), d.precision("balance_in_account_currency")
),
reverse_dr_or_cr: 0,
"debit": 0,
"credit": 0,
}
)
elif d.get("balance_in_base_currency") and not d.get("new_balance_in_base_currency"):
# Base currency has balance
dr_or_cr = "credit" if d.get("balance_in_base_currency") > 0 else "debit"
reverse_dr_or_cr = "debit" if dr_or_cr == "credit" else "credit"
journal_account.update(
{
dr_or_cr: flt(
abs(d.get("balance_in_base_currency")), d.precision("balance_in_base_currency")
),
reverse_dr_or_cr: 0,
"debit_in_account_currency": 0,
"credit_in_account_currency": 0,
}
)
journal_entry_accounts.append(journal_account)
journal_entry_accounts.append(
{
"account": unrealized_exchange_gain_loss_account,
"balance": get_balance_on(unrealized_exchange_gain_loss_account),
"debit": abs(self.gain_loss_booked) if self.gain_loss_booked < 0 else 0,
"credit": abs(self.gain_loss_booked) if self.gain_loss_booked > 0 else 0,
"debit_in_account_currency": abs(self.gain_loss_booked) if self.gain_loss_booked < 0 else 0,
"credit_in_account_currency": self.gain_loss_booked if self.gain_loss_booked > 0 else 0,
"cost_center": erpnext.get_default_cost_center(self.company),
"exchange_rate": 1,
"reference_type": "Exchange Rate Revaluation",
"reference_name": self.name,
}
)
journal_entry.set("accounts", journal_entry_accounts)
journal_entry.set_total_debit_credit()
journal_entry.save()
return journal_entry
def make_jv_for_revaluation(self):
if self.gain_loss_unbooked == 0:
return
accounts = [x for x in self.accounts if not x.zero_balance]
if not accounts:
return
unrealized_exchange_gain_loss_account = self.get_for_unrealized_gain_loss_account()
journal_entry = frappe.new_doc("Journal Entry")
journal_entry.voucher_type = "Exchange Rate Revaluation"
@@ -154,7 +427,10 @@ class ExchangeRateRevaluation(Document):
journal_entry.multi_currency = 1
journal_entry_accounts = []
for d in self.accounts:
for d in accounts:
if not flt(d.get("balance_in_account_currency"), d.precision("balance_in_account_currency")):
continue
dr_or_cr = (
"debit_in_account_currency"
if d.get("balance_in_account_currency") > 0
@@ -179,6 +455,7 @@ class ExchangeRateRevaluation(Document):
dr_or_cr: flt(
abs(d.get("balance_in_account_currency")), d.precision("balance_in_account_currency")
),
"cost_center": erpnext.get_default_cost_center(self.company),
"exchange_rate": flt(d.get("new_exchange_rate"), d.precision("new_exchange_rate")),
"reference_type": "Exchange Rate Revaluation",
"reference_name": self.name,
@@ -196,63 +473,129 @@ class ExchangeRateRevaluation(Document):
reverse_dr_or_cr: flt(
abs(d.get("balance_in_account_currency")), d.precision("balance_in_account_currency")
),
"cost_center": erpnext.get_default_cost_center(self.company),
"exchange_rate": flt(d.get("current_exchange_rate"), d.precision("current_exchange_rate")),
"reference_type": "Exchange Rate Revaluation",
"reference_name": self.name,
}
)
journal_entry_accounts.append(
{
"account": unrealized_exchange_gain_loss_account,
"balance": get_balance_on(unrealized_exchange_gain_loss_account),
"debit_in_account_currency": abs(self.total_gain_loss) if self.total_gain_loss < 0 else 0,
"credit_in_account_currency": self.total_gain_loss if self.total_gain_loss > 0 else 0,
"exchange_rate": 1,
"reference_type": "Exchange Rate Revaluation",
"reference_name": self.name,
}
)
journal_entry.set("accounts", journal_entry_accounts)
journal_entry.set_amounts_in_company_currency()
journal_entry.set_total_debit_credit()
return journal_entry.as_dict()
self.gain_loss_unbooked += journal_entry.difference - self.gain_loss_unbooked
journal_entry.append(
"accounts",
{
"account": unrealized_exchange_gain_loss_account,
"balance": get_balance_on(unrealized_exchange_gain_loss_account),
"debit_in_account_currency": abs(self.gain_loss_unbooked)
if self.gain_loss_unbooked < 0
else 0,
"credit_in_account_currency": self.gain_loss_unbooked if self.gain_loss_unbooked > 0 else 0,
"cost_center": erpnext.get_default_cost_center(self.company),
"exchange_rate": 1,
"reference_type": "Exchange Rate Revaluation",
"reference_name": self.name,
},
)
journal_entry.set_amounts_in_company_currency()
journal_entry.set_total_debit_credit()
journal_entry.save()
return journal_entry
def calculate_exchange_rate_using_last_gle(company, account, party_type, party):
"""
Use last GL entry to calculate exchange rate
"""
last_exchange_rate = None
if company and account:
gl = qb.DocType("GL Entry")
# build conditions
conditions = []
conditions.append(gl.company == company)
conditions.append(gl.account == account)
conditions.append(gl.is_cancelled == 0)
conditions.append((gl.debit > 0) | (gl.credit > 0))
conditions.append((gl.debit_in_account_currency > 0) | (gl.credit_in_account_currency > 0))
if party_type:
conditions.append(gl.party_type == party_type)
if party:
conditions.append(gl.party == party)
voucher_type, voucher_no = (
qb.from_(gl)
.select(gl.voucher_type, gl.voucher_no)
.where(Criterion.all(conditions))
.orderby(gl.posting_date, order=Order.desc)
.limit(1)
.run()[0]
)
last_exchange_rate = (
qb.from_(gl)
.select((gl.debit - gl.credit) / (gl.debit_in_account_currency - gl.credit_in_account_currency))
.where(
(gl.voucher_type == voucher_type) & (gl.voucher_no == voucher_no) & (gl.account == account)
)
.orderby(gl.posting_date, order=Order.desc)
.limit(1)
.run()[0][0]
)
return last_exchange_rate
@frappe.whitelist()
def get_account_details(account, company, posting_date, party_type=None, party=None):
def get_account_details(
company, posting_date, account, party_type=None, party=None, rounding_loss_allowance=None
):
if not (company and posting_date):
frappe.throw(_("Company and Posting Date is mandatory"))
account_currency, account_type = frappe.get_cached_value(
"Account", account, ["account_currency", "account_type"]
)
if account_type in ["Receivable", "Payable"] and not (party_type and party):
frappe.throw(_("Party Type and Party is mandatory for {0} account").format(account_type))
account_details = {}
company_currency = erpnext.get_company_currency(company)
balance = get_balance_on(
account, date=posting_date, party_type=party_type, party=party, in_account_currency=False
)
account_details = {
"account_currency": account_currency,
}
account_balance = ExchangeRateRevaluation.get_account_balance_from_gle(
company=company,
posting_date=posting_date,
account=account,
party_type=party_type,
party=party,
rounding_loss_allowance=rounding_loss_allowance,
)
if balance:
balance_in_account_currency = get_balance_on(
account, date=posting_date, party_type=party_type, party=party
if account_balance and (
account_balance[0].balance or account_balance[0].balance_in_account_currency
):
account_with_new_balance = ExchangeRateRevaluation.calculate_new_account_balance(
company, posting_date, account_balance
)
current_exchange_rate = (
balance / balance_in_account_currency if balance_in_account_currency else 0
)
new_exchange_rate = get_exchange_rate(account_currency, company_currency, posting_date)
new_balance_in_base_currency = balance_in_account_currency * new_exchange_rate
account_details = account_details.update(
row = account_with_new_balance[0]
account_details.update(
{
"balance_in_base_currency": balance,
"balance_in_account_currency": balance_in_account_currency,
"current_exchange_rate": current_exchange_rate,
"new_exchange_rate": new_exchange_rate,
"new_balance_in_base_currency": new_balance_in_base_currency,
"balance_in_base_currency": row["balance_in_base_currency"],
"balance_in_account_currency": row["balance_in_account_currency"],
"current_exchange_rate": row["current_exchange_rate"],
"new_exchange_rate": row["new_exchange_rate"],
"new_balance_in_base_currency": row["new_balance_in_base_currency"],
"new_balance_in_account_currency": row["new_balance_in_account_currency"],
"zero_balance": row["zero_balance"],
"gain_loss": row["gain_loss"],
}
)

View File

@@ -10,14 +10,21 @@
"party",
"column_break_2",
"account_currency",
"account_balances",
"balance_in_account_currency",
"column_break_46yz",
"new_balance_in_account_currency",
"balances",
"current_exchange_rate",
"balance_in_base_currency",
"column_break_9",
"column_break_xown",
"new_exchange_rate",
"column_break_9",
"balance_in_base_currency",
"column_break_ukce",
"new_balance_in_base_currency",
"gain_loss"
"section_break_ngrs",
"gain_loss",
"zero_balance"
],
"fields": [
{
@@ -78,7 +85,7 @@
},
{
"fieldname": "column_break_9",
"fieldtype": "Column Break"
"fieldtype": "Section Break"
},
{
"fieldname": "new_exchange_rate",
@@ -102,11 +109,45 @@
"label": "Gain/Loss",
"options": "Company:company:default_currency",
"read_only": 1
},
{
"default": "0",
"description": "This Account has '0' balance in either Base Currency or Account Currency",
"fieldname": "zero_balance",
"fieldtype": "Check",
"label": "Zero Balance"
},
{
"fieldname": "new_balance_in_account_currency",
"fieldtype": "Currency",
"label": "New Balance In Account Currency",
"options": "account_currency",
"read_only": 1
},
{
"fieldname": "account_balances",
"fieldtype": "Section Break"
},
{
"fieldname": "column_break_46yz",
"fieldtype": "Column Break"
},
{
"fieldname": "column_break_xown",
"fieldtype": "Column Break"
},
{
"fieldname": "column_break_ukce",
"fieldtype": "Column Break"
},
{
"fieldname": "section_break_ngrs",
"fieldtype": "Section Break"
}
],
"istable": 1,
"links": [],
"modified": "2022-11-17 10:26:18.302728",
"modified": "2022-12-29 19:38:52.915295",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Exchange Rate Revaluation Account",

View File

@@ -12,7 +12,7 @@ from frappe.utils import add_days, add_years, cstr, getdate
class FiscalYear(Document):
@frappe.whitelist()
def set_as_default(self):
frappe.db.set_value("Global Defaults", None, "current_fiscal_year", self.name)
frappe.db.set_single_value("Global Defaults", "current_fiscal_year", self.name)
global_defaults = frappe.get_doc("Global Defaults")
global_defaults.check_permission("write")
global_defaults.on_update()

View File

@@ -95,7 +95,15 @@ class GLEntry(Document):
)
# Zero value transaction is not allowed
if not (flt(self.debit, self.precision("debit")) or flt(self.credit, self.precision("credit"))):
if not (
flt(self.debit, self.precision("debit"))
or flt(self.credit, self.precision("credit"))
or (
self.voucher_type == "Journal Entry"
and frappe.get_cached_value("Journal Entry", self.voucher_no, "voucher_type")
== "Exchange Gain Or Loss"
)
):
frappe.throw(
_("{0} {1}: Either debit or credit amount is required for {2}").format(
self.voucher_type, self.voucher_no, self.account

View File

@@ -8,7 +8,7 @@ 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'];
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', "Repost Payment Ledger", 'Asset Depreciation Schedule'];
},
refresh: function(frm) {

View File

@@ -88,7 +88,7 @@
"label": "Entry Type",
"oldfieldname": "voucher_type",
"oldfieldtype": "Select",
"options": "Journal Entry\nInter Company Journal Entry\nBank Entry\nCash Entry\nCredit Card Entry\nDebit Note\nCredit Note\nContra Entry\nExcise Entry\nWrite Off Entry\nOpening Entry\nDepreciation Entry\nExchange Rate Revaluation\nDeferred Revenue\nDeferred Expense",
"options": "Journal Entry\nInter Company Journal Entry\nBank Entry\nCash Entry\nCredit Card Entry\nDebit Note\nCredit Note\nContra Entry\nExcise Entry\nWrite Off Entry\nOpening Entry\nDepreciation Entry\nExchange Rate Revaluation\nExchange Gain Or Loss\nDeferred Revenue\nDeferred Expense",
"reqd": 1,
"search_index": 1
},
@@ -539,7 +539,7 @@
"idx": 176,
"is_submittable": 1,
"links": [],
"modified": "2022-06-23 22:01:32.348337",
"modified": "2023-03-01 14:58:59.286591",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Journal Entry",

View File

@@ -6,7 +6,7 @@ import json
import frappe
from frappe import _, msgprint, scrub
from frappe.utils import cint, cstr, flt, fmt_money, formatdate, get_link_to_form, nowdate
from frappe.utils import cstr, flt, fmt_money, formatdate, get_link_to_form, nowdate
import erpnext
from erpnext.accounts.deferred_revenue import get_deferred_booking_accounts
@@ -23,6 +23,9 @@ from erpnext.accounts.utils import (
get_stock_accounts,
get_stock_and_account_balance,
)
from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule import (
get_depr_schedule,
)
from erpnext.controllers.accounts_controller import AccountsController
@@ -34,9 +37,6 @@ class JournalEntry(AccountsController):
def __init__(self, *args, **kwargs):
super(JournalEntry, self).__init__(*args, **kwargs)
def get_feed(self):
return self.voucher_type
def validate(self):
if self.voucher_type == "Opening Entry":
self.is_opening = "Yes"
@@ -51,7 +51,7 @@ class JournalEntry(AccountsController):
self.validate_multi_currency()
self.set_amounts_in_company_currency()
self.validate_debit_credit_amount()
self.set_total_debit_credit()
# Do not validate while importing via data import
if not frappe.flags.in_import:
self.validate_total_debit_and_credit()
@@ -69,6 +69,7 @@ class JournalEntry(AccountsController):
self.validate_empty_accounts_table()
self.set_account_and_party_balance()
self.validate_inter_company_accounts()
self.validate_depr_entry_voucher_type()
if self.docstatus == 0:
self.apply_tax_withholding()
@@ -81,6 +82,7 @@ class JournalEntry(AccountsController):
self.check_credit_limit()
self.make_gl_entries()
self.update_advance_paid()
self.update_asset_value()
self.update_inter_company_jv()
self.update_invoice_discounting()
@@ -88,7 +90,13 @@ class JournalEntry(AccountsController):
from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
unlink_ref_doc_from_payment_entries(self)
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry", "Payment Ledger Entry")
self.ignore_linked_doctypes = (
"GL Entry",
"Stock Ledger Entry",
"Payment Ledger Entry",
"Repost Payment Ledger",
"Repost Payment Ledger Items",
)
self.make_gl_entries(1)
self.update_advance_paid()
self.unlink_advance_entry_reference()
@@ -123,6 +131,13 @@ class JournalEntry(AccountsController):
if self.total_credit != doc.total_debit or self.total_debit != doc.total_credit:
frappe.throw(_("Total Credit/ Debit Amount should be same as linked Journal Entry"))
def validate_depr_entry_voucher_type(self):
if (
any(d.account_type == "Depreciation" for d in self.get("accounts"))
and self.voucher_type != "Depreciation Entry"
):
frappe.throw(_("Journal Entry type should be set as Depreciation Entry for asset depreciation"))
def validate_stock_accounts(self):
stock_accounts = get_stock_accounts(self.company, self.doctype, self.name)
for account in stock_accounts:
@@ -225,6 +240,34 @@ class JournalEntry(AccountsController):
for d in to_remove:
self.remove(d)
def update_asset_value(self):
if self.flags.planned_depr_entry or self.voucher_type != "Depreciation Entry":
return
for d in self.get("accounts"):
if (
d.reference_type == "Asset"
and d.reference_name
and d.account_type == "Depreciation"
and d.debit
):
asset = frappe.get_doc("Asset", d.reference_name)
if asset.calculate_depreciation:
fb_idx = 1
if self.finance_book:
for fb_row in asset.get("finance_books"):
if fb_row.finance_book == self.finance_book:
fb_idx = fb_row.idx
break
fb_row = asset.get("finance_books")[fb_idx - 1]
fb_row.value_after_depreciation -= d.debit
fb_row.db_update()
else:
asset.db_set("value_after_depreciation", asset.value_after_depreciation - d.debit)
asset.set_status()
def update_inter_company_jv(self):
if (
self.voucher_type == "Inter Company Journal Entry"
@@ -283,19 +326,50 @@ class JournalEntry(AccountsController):
d.db_update()
def unlink_asset_reference(self):
if self.voucher_type != "Depreciation Entry":
return
for d in self.get("accounts"):
if d.reference_type == "Asset" and d.reference_name:
if (
d.reference_type == "Asset"
and d.reference_name
and d.account_type == "Depreciation"
and d.debit
):
asset = frappe.get_doc("Asset", d.reference_name)
for s in asset.get("schedules"):
if s.journal_entry == self.name:
s.db_set("journal_entry", None)
idx = cint(s.finance_book_id) or 1
finance_books = asset.get("finance_books")[idx - 1]
finance_books.value_after_depreciation += s.depreciation_amount
finance_books.db_update()
if asset.calculate_depreciation:
je_found = False
asset.set_status()
for fb_row in asset.get("finance_books"):
if je_found:
break
depr_schedule = get_depr_schedule(asset.name, "Active", fb_row.finance_book)
for s in depr_schedule or []:
if s.journal_entry == self.name:
s.db_set("journal_entry", None)
fb_row.value_after_depreciation += d.debit
fb_row.db_update()
je_found = True
break
if not je_found:
fb_idx = 1
if self.finance_book:
for fb_row in asset.get("finance_books"):
if fb_row.finance_book == self.finance_book:
fb_idx = fb_row.idx
break
fb_row = asset.get("finance_books")[fb_idx - 1]
fb_row.value_after_depreciation += d.debit
fb_row.db_update()
else:
asset.db_set("value_after_depreciation", asset.value_after_depreciation + d.debit)
asset.set_status()
def unlink_inter_company_jv(self):
if (
@@ -592,28 +666,29 @@ class JournalEntry(AccountsController):
d.against_account = frappe.db.get_value(d.reference_type, d.reference_name, field)
else:
for d in self.get("accounts"):
if flt(d.debit > 0):
if flt(d.debit) > 0:
accounts_debited.append(d.party or d.account)
if flt(d.credit) > 0:
accounts_credited.append(d.party or d.account)
for d in self.get("accounts"):
if flt(d.debit > 0):
if flt(d.debit) > 0:
d.against_account = ", ".join(list(set(accounts_credited)))
if flt(d.credit > 0):
if flt(d.credit) > 0:
d.against_account = ", ".join(list(set(accounts_debited)))
def validate_debit_credit_amount(self):
for d in self.get("accounts"):
if not flt(d.debit) and not flt(d.credit):
frappe.throw(_("Row {0}: Both Debit and Credit values cannot be zero").format(d.idx))
if not (self.voucher_type == "Exchange Gain Or Loss" and self.multi_currency):
for d in self.get("accounts"):
if not flt(d.debit) and not flt(d.credit):
frappe.throw(_("Row {0}: Both Debit and Credit values cannot be zero").format(d.idx))
def validate_total_debit_and_credit(self):
self.set_total_debit_credit()
if self.difference:
frappe.throw(
_("Total Debit must be equal to Total Credit. The difference is {0}").format(self.difference)
)
if not (self.voucher_type == "Exchange Gain Or Loss" and self.multi_currency):
if self.difference:
frappe.throw(
_("Total Debit must be equal to Total Credit. The difference is {0}").format(self.difference)
)
def set_total_debit_credit(self):
self.total_debit, self.total_credit, self.difference = 0, 0, 0
@@ -651,16 +726,17 @@ class JournalEntry(AccountsController):
self.set_exchange_rate()
def set_amounts_in_company_currency(self):
for d in self.get("accounts"):
d.debit_in_account_currency = flt(
d.debit_in_account_currency, d.precision("debit_in_account_currency")
)
d.credit_in_account_currency = flt(
d.credit_in_account_currency, d.precision("credit_in_account_currency")
)
if not (self.voucher_type == "Exchange Gain Or Loss" and self.multi_currency):
for d in self.get("accounts"):
d.debit_in_account_currency = flt(
d.debit_in_account_currency, d.precision("debit_in_account_currency")
)
d.credit_in_account_currency = flt(
d.credit_in_account_currency, d.precision("credit_in_account_currency")
)
d.debit = flt(d.debit_in_account_currency * flt(d.exchange_rate), d.precision("debit"))
d.credit = flt(d.credit_in_account_currency * flt(d.exchange_rate), d.precision("credit"))
d.debit = flt(d.debit_in_account_currency * flt(d.exchange_rate), d.precision("debit"))
d.credit = flt(d.credit_in_account_currency * flt(d.exchange_rate), d.precision("credit"))
def set_exchange_rate(self):
for d in self.get("accounts"):
@@ -759,7 +835,7 @@ class JournalEntry(AccountsController):
pay_to_recd_from = d.party
if pay_to_recd_from and pay_to_recd_from == d.party:
party_amount += d.debit_in_account_currency or d.credit_in_account_currency
party_amount += flt(d.debit_in_account_currency) or flt(d.credit_in_account_currency)
party_account_currency = d.account_currency
elif frappe.get_cached_value("Account", d.account, "account_type") in ["Bank", "Cash"]:
@@ -789,7 +865,7 @@ class JournalEntry(AccountsController):
def build_gl_map(self):
gl_map = []
for d in self.get("accounts"):
if d.debit or d.credit:
if d.debit or d.credit or (self.voucher_type == "Exchange Gain Or Loss"):
r = [d.user_remark, self.remark]
r = [x for x in r if x]
remarks = "\n".join(r)
@@ -827,6 +903,8 @@ class JournalEntry(AccountsController):
def make_gl_entries(self, cancel=0, adv_adj=0):
from erpnext.accounts.general_ledger import make_gl_entries
merge_entries = frappe.db.get_single_value("Accounts Settings", "merge_similar_account_heads")
gl_map = self.build_gl_map()
if self.voucher_type in ("Deferred Revenue", "Deferred Expense"):
update_outstanding = "No"
@@ -834,10 +912,16 @@ class JournalEntry(AccountsController):
update_outstanding = "Yes"
if gl_map:
make_gl_entries(gl_map, cancel=cancel, adv_adj=adv_adj, update_outstanding=update_outstanding)
make_gl_entries(
gl_map,
cancel=cancel,
adv_adj=adv_adj,
merge_entries=merge_entries,
update_outstanding=update_outstanding,
)
@frappe.whitelist()
def get_balance(self):
def get_balance(self, difference_account=None):
if not self.get("accounts"):
msgprint(_("'Entries' cannot be empty"), raise_exception=True)
else:
@@ -852,7 +936,13 @@ class JournalEntry(AccountsController):
blank_row = d
if not blank_row:
blank_row = self.append("accounts", {})
blank_row = self.append(
"accounts",
{
"account": difference_account,
"cost_center": erpnext.get_default_cost_center(self.company),
},
)
blank_row.exchange_rate = 1
if diff > 0:
@@ -862,6 +952,7 @@ class JournalEntry(AccountsController):
blank_row.debit_in_account_currency = abs(diff)
blank_row.debit = abs(diff)
self.set_total_debit_credit()
self.validate_total_debit_and_credit()
@frappe.whitelist()

View File

@@ -105,8 +105,8 @@ class TestJournalEntry(unittest.TestCase):
elif test_voucher.doctype in ["Sales Order", "Purchase Order"]:
# if test_voucher is a Sales Order/Purchase Order, test error on cancellation of test_voucher
frappe.db.set_value(
"Accounts Settings", "Accounts Settings", "unlink_advance_payment_on_cancelation_of_order", 0
frappe.db.set_single_value(
"Accounts Settings", "unlink_advance_payment_on_cancelation_of_order", 0
)
submitted_voucher = frappe.get_doc(test_voucher.doctype, test_voucher.name)
self.assertRaises(frappe.LinkExistsError, submitted_voucher.cancel)
@@ -287,10 +287,6 @@ class TestJournalEntry(unittest.TestCase):
jv.submit()
def test_inter_company_jv(self):
frappe.db.set_value("Account", "Sales Expenses - _TC", "inter_company_account", 1)
frappe.db.set_value("Account", "Buildings - _TC", "inter_company_account", 1)
frappe.db.set_value("Account", "Sales Expenses - _TC1", "inter_company_account", 1)
frappe.db.set_value("Account", "Buildings - _TC1", "inter_company_account", 1)
jv = make_journal_entry(
"Sales Expenses - _TC",
"Buildings - _TC",

View File

@@ -2,6 +2,21 @@
// For license information, please see license.txt
frappe.ui.form.on("Journal Entry Template", {
onload: function(frm) {
if(frm.is_new()) {
frappe.call({
type: "GET",
method: "erpnext.accounts.doctype.journal_entry_template.journal_entry_template.get_naming_series",
callback: function(r){
if(r.message) {
frm.set_df_property("naming_series", "options", r.message.split("\n"));
frm.set_value("naming_series", r.message.split("\n")[0]);
frm.refresh_field("naming_series");
}
}
});
}
},
refresh: function(frm) {
frappe.model.set_default_values(frm.doc);
@@ -19,18 +34,6 @@ frappe.ui.form.on("Journal Entry Template", {
return { filters: filters };
});
frappe.call({
type: "GET",
method: "erpnext.accounts.doctype.journal_entry_template.journal_entry_template.get_naming_series",
callback: function(r){
if(r.message){
frm.set_df_property("naming_series", "options", r.message.split("\n"));
frm.set_value("naming_series", r.message.split("\n")[0]);
frm.refresh_field("naming_series");
}
}
});
},
voucher_type: function(frm) {
var add_accounts = function(doc, r) {

View File

@@ -4,7 +4,7 @@
import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils.background_jobs import is_job_queued
from frappe.utils.background_jobs import is_job_enqueued
from erpnext.accounts.doctype.account.account import merge_account
@@ -17,13 +17,14 @@ class LedgerMerge(Document):
if is_scheduler_inactive() and not frappe.flags.in_test:
frappe.throw(_("Scheduler is inactive. Cannot merge accounts."), title=_("Scheduler Inactive"))
if not is_job_queued(self.name):
job_id = f"ledger_merge::{self.name}"
if not is_job_enqueued(job_id):
enqueue(
start_merge,
queue="default",
timeout=6000,
event="ledger_merge",
job_name=self.name,
job_id=job_id,
docname=self.name,
now=frappe.conf.developer_mode or frappe.flags.in_test,
)

View File

@@ -6,7 +6,7 @@ import frappe
from frappe import _, scrub
from frappe.model.document import Document
from frappe.utils import flt, nowdate
from frappe.utils.background_jobs import enqueue, is_job_queued
from frappe.utils.background_jobs import enqueue, is_job_enqueued
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
get_accounting_dimensions,
@@ -212,13 +212,15 @@ class OpeningInvoiceCreationTool(Document):
if is_scheduler_inactive() and not frappe.flags.in_test:
frappe.throw(_("Scheduler is inactive. Cannot import data."), title=_("Scheduler Inactive"))
if not is_job_queued(self.name):
job_id = f"opening_invoice::{self.name}"
if not is_job_enqueued(job_id):
enqueue(
start_import,
queue="default",
timeout=6000,
event="opening_invoice_creation",
job_name=self.name,
job_id=job_id,
invoices=invoices,
now=frappe.conf.developer_mode or frappe.flags.in_test,
)

View File

@@ -7,7 +7,7 @@ cur_frm.cscript.tax_table = "Advance Taxes and Charges";
frappe.ui.form.on('Payment Entry', {
onload: function(frm) {
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice'];
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', "Repost Payment Ledger"];
if(frm.doc.__islocal) {
if (!frm.doc.paid_from) frm.set_value("paid_from_account_currency", null);
@@ -217,7 +217,6 @@ frappe.ui.form.on('Payment Entry', {
frm.toggle_display("set_exchange_gain_loss",
frm.doc.paid_amount && frm.doc.received_amount && frm.doc.difference_amount);
frm.refresh_fields();
},
set_dynamic_labels: function(frm) {
@@ -245,8 +244,6 @@ frappe.ui.form.on('Payment Entry', {
frm.set_currency_labels(["total_amount", "outstanding_amount", "allocated_amount"],
party_account_currency, "references");
frm.set_currency_labels(["amount"], company_currency, "deductions");
cur_frm.set_df_property("source_exchange_rate", "description",
("1 " + frm.doc.paid_from_account_currency + " = [?] " + company_currency));
@@ -907,7 +904,7 @@ frappe.ui.form.on('Payment Entry', {
function(d) { return flt(d.amount) }));
frm.set_value("difference_amount", difference_amount - total_deductions +
frm.doc.base_total_taxes_and_charges);
flt(frm.doc.base_total_taxes_and_charges));
frm.events.hide_unhide_fields(frm);
},
@@ -973,29 +970,48 @@ frappe.ui.form.on('Payment Entry', {
},
callback: function(r, rt) {
if(r.message) {
var write_off_row = $.map(frm.doc["deductions"] || [], function(t) {
const write_off_row = $.map(frm.doc["deductions"] || [], function(t) {
return t.account==r.message[account] ? t : null; });
var row = [];
var difference_amount = flt(frm.doc.difference_amount,
const difference_amount = flt(frm.doc.difference_amount,
precision("difference_amount"));
if (!write_off_row.length && difference_amount) {
row = frm.add_child("deductions");
row.account = r.message[account];
row.cost_center = r.message["cost_center"];
} else {
row = write_off_row[0];
}
const add_deductions = (details) => {
let row = null;
if (!write_off_row.length && difference_amount) {
row = frm.add_child("deductions");
row.account = details[account];
row.cost_center = details["cost_center"];
} else {
row = write_off_row[0];
}
if (row) {
row.amount = flt(row.amount) + difference_amount;
} else {
frappe.msgprint(__("No gain or loss in the exchange rate"))
}
if (row) {
row.amount = flt(row.amount) + difference_amount;
} else {
frappe.msgprint(__("No gain or loss in the exchange rate"))
}
refresh_field("deductions");
};
refresh_field("deductions");
if (!r.message[account]) {
frappe.prompt({
label: __("Please Specify Account"),
fieldname: account,
fieldtype: "Link",
options: "Account",
get_query: () => ({
filters: {
company: frm.doc.company,
}
})
}, (values) => {
const details = Object.assign({}, r.message, values);
add_deductions(details);
}, __(frappe.unscrub(account)));
} else {
add_deductions(r.message);
}
frm.events.set_unallocated_amount(frm);
}

View File

@@ -239,7 +239,7 @@
"depends_on": "paid_from",
"fieldname": "paid_from_account_currency",
"fieldtype": "Link",
"label": "Account Currency",
"label": "Account Currency (From)",
"options": "Currency",
"print_hide": 1,
"read_only": 1,
@@ -249,7 +249,7 @@
"depends_on": "paid_from",
"fieldname": "paid_from_account_balance",
"fieldtype": "Currency",
"label": "Account Balance",
"label": "Account Balance (From)",
"options": "paid_from_account_currency",
"print_hide": 1,
"read_only": 1
@@ -272,7 +272,7 @@
"depends_on": "paid_to",
"fieldname": "paid_to_account_currency",
"fieldtype": "Link",
"label": "Account Currency",
"label": "Account Currency (To)",
"options": "Currency",
"print_hide": 1,
"read_only": 1,
@@ -282,7 +282,7 @@
"depends_on": "paid_to",
"fieldname": "paid_to_account_balance",
"fieldtype": "Currency",
"label": "Account Balance",
"label": "Account Balance (To)",
"options": "paid_to_account_currency",
"print_hide": 1,
"read_only": 1
@@ -304,7 +304,8 @@
{
"fieldname": "source_exchange_rate",
"fieldtype": "Float",
"label": "Exchange Rate",
"label": "Source Exchange Rate",
"precision": "9",
"print_hide": 1,
"reqd": 1
},
@@ -333,7 +334,8 @@
{
"fieldname": "target_exchange_rate",
"fieldtype": "Float",
"label": "Exchange Rate",
"label": "Target Exchange Rate",
"precision": "9",
"print_hide": 1,
"reqd": 1
},
@@ -631,14 +633,14 @@
"depends_on": "eval:doc.party_type == 'Supplier'",
"fieldname": "purchase_taxes_and_charges_template",
"fieldtype": "Link",
"label": "Taxes and Charges Template",
"label": "Purchase Taxes and Charges Template",
"options": "Purchase Taxes and Charges Template"
},
{
"depends_on": "eval: doc.party_type == 'Customer'",
"fieldname": "sales_taxes_and_charges_template",
"fieldtype": "Link",
"label": "Taxes and Charges Template",
"label": "Sales Taxes and Charges Template",
"options": "Sales Taxes and Charges Template"
},
{
@@ -731,7 +733,7 @@
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2022-02-23 20:08:39.559814",
"modified": "2023-02-14 04:52:30.478523",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry",

View File

@@ -60,6 +60,7 @@ class PaymentEntry(AccountsController):
def validate(self):
self.setup_party_account_field()
self.set_missing_values()
self.set_missing_ref_details()
self.validate_payment_type()
self.validate_party_details()
self.set_exchange_rate()
@@ -92,7 +93,13 @@ class PaymentEntry(AccountsController):
self.set_status()
def on_cancel(self):
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry", "Payment Ledger Entry")
self.ignore_linked_doctypes = (
"GL Entry",
"Stock Ledger Entry",
"Payment Ledger Entry",
"Repost Payment Ledger",
"Repost Payment Ledger Items",
)
self.make_gl_entries(cancel=1)
self.update_outstanding_amounts()
self.update_advance_paid()
@@ -141,19 +148,57 @@ class PaymentEntry(AccountsController):
)
def validate_allocated_amount(self):
for d in self.get("references"):
if self.payment_type == "Internal Transfer":
return
latest_references = get_outstanding_reference_documents(
{
"posting_date": self.posting_date,
"company": self.company,
"party_type": self.party_type,
"payment_type": self.payment_type,
"party": self.party,
"party_account": self.paid_from if self.payment_type == "Receive" else self.paid_to,
}
)
# Group latest_references by (voucher_type, voucher_no)
latest_lookup = {}
for d in latest_references:
d = frappe._dict(d)
latest_lookup.update({(d.voucher_type, d.voucher_no): d})
for d in self.get("references").copy():
latest = latest_lookup.get((d.reference_doctype, d.reference_name))
# The reference has already been fully paid
if not latest:
frappe.throw(
_("{0} {1} has already been fully paid.").format(d.reference_doctype, d.reference_name)
)
# The reference has already been partly paid
elif (
latest.outstanding_amount < latest.invoice_amount
and d.outstanding_amount != latest.outstanding_amount
):
frappe.throw(
_(
"{0} {1} has already been partly paid. Please use the 'Get Outstanding Invoice' button to get the latest outstanding amount."
).format(d.reference_doctype, d.reference_name)
)
d.outstanding_amount = latest.outstanding_amount
fail_message = _("Row #{0}: Allocated Amount cannot be greater than outstanding amount.")
if (flt(d.allocated_amount)) > 0:
if flt(d.allocated_amount) > flt(d.outstanding_amount):
frappe.throw(
_("Row #{0}: Allocated Amount cannot be greater than outstanding amount.").format(d.idx)
)
frappe.throw(fail_message.format(d.idx))
# Check for negative outstanding invoices as well
if flt(d.allocated_amount) < 0:
if flt(d.allocated_amount) < flt(d.outstanding_amount):
frappe.throw(
_("Row #{0}: Allocated Amount cannot be greater than outstanding amount.").format(d.idx)
)
frappe.throw(fail_message.format(d.idx))
def delink_advance_entry_references(self):
for reference in self.references:
@@ -213,11 +258,16 @@ class PaymentEntry(AccountsController):
else self.paid_to_account_currency
)
self.set_missing_ref_details()
def set_missing_ref_details(self, force=False):
def set_missing_ref_details(
self, force: bool = False, update_ref_details_only_for: list | None = None
) -> None:
for d in self.get("references"):
if d.allocated_amount:
if update_ref_details_only_for and (
not (d.reference_doctype, d.reference_name) in update_ref_details_only_for
):
continue
ref_details = get_reference_details(
d.reference_doctype, d.reference_name, self.party_account_currency
)
@@ -247,7 +297,7 @@ class PaymentEntry(AccountsController):
self.set_target_exchange_rate(ref_doc)
def set_source_exchange_rate(self, ref_doc=None):
if self.paid_from and not self.source_exchange_rate:
if self.paid_from:
if self.paid_from_account_currency == self.company_currency:
self.source_exchange_rate = 1
else:
@@ -361,7 +411,7 @@ class PaymentEntry(AccountsController):
for k, v in no_oustanding_refs.items():
frappe.msgprint(
_(
"{} - {} now have {} as they had no outstanding amount left before submitting the Payment Entry."
"{} - {} now has {} as it had no outstanding amount left before submitting the Payment Entry."
).format(
_(k),
frappe.bold(", ".join(d.reference_name for d in v)),
@@ -410,7 +460,7 @@ class PaymentEntry(AccountsController):
for ref in self.get("references"):
if ref.payment_term and ref.reference_name:
key = (ref.payment_term, ref.reference_name)
key = (ref.payment_term, ref.reference_name, ref.reference_doctype)
invoice_payment_amount_map.setdefault(key, 0.0)
invoice_payment_amount_map[key] += ref.allocated_amount
@@ -418,20 +468,37 @@ class PaymentEntry(AccountsController):
payment_schedule = frappe.get_all(
"Payment Schedule",
filters={"parent": ref.reference_name},
fields=["paid_amount", "payment_amount", "payment_term", "discount", "outstanding"],
fields=[
"paid_amount",
"payment_amount",
"payment_term",
"discount",
"outstanding",
"discount_type",
],
)
for term in payment_schedule:
invoice_key = (term.payment_term, ref.reference_name)
invoice_key = (term.payment_term, ref.reference_name, ref.reference_doctype)
invoice_paid_amount_map.setdefault(invoice_key, {})
invoice_paid_amount_map[invoice_key]["outstanding"] = term.outstanding
invoice_paid_amount_map[invoice_key]["discounted_amt"] = ref.total_amount * (
term.discount / 100
)
if not (term.discount_type and term.discount):
continue
if term.discount_type == "Percentage":
invoice_paid_amount_map[invoice_key]["discounted_amt"] = ref.total_amount * (
term.discount / 100
)
else:
invoice_paid_amount_map[invoice_key]["discounted_amt"] = term.discount
for idx, (key, allocated_amount) in enumerate(invoice_payment_amount_map.items(), 1):
if not invoice_paid_amount_map.get(key):
frappe.throw(_("Payment term {0} not used in {1}").format(key[0], key[1]))
allocated_amount = self.get_allocated_amount_in_transaction_currency(
allocated_amount, key[2], key[1]
)
outstanding = flt(invoice_paid_amount_map.get(key, {}).get("outstanding"))
discounted_amt = flt(invoice_paid_amount_map.get(key, {}).get("discounted_amt"))
@@ -466,6 +533,33 @@ class PaymentEntry(AccountsController):
(allocated_amount - discounted_amt, discounted_amt, allocated_amount, key[1], key[0]),
)
def get_allocated_amount_in_transaction_currency(
self, allocated_amount, reference_doctype, reference_docname
):
"""
Payment Entry could be in base currency while reference's payment schedule
is always in transaction currency.
E.g.
* SI with base=INR and currency=USD
* SI with payment schedule in USD
* PE in INR (accounting done in base currency)
"""
ref_currency, ref_exchange_rate = frappe.db.get_value(
reference_doctype, reference_docname, ["currency", "conversion_rate"]
)
is_single_currency = self.paid_from_account_currency == self.paid_to_account_currency
# PE in different currency
reference_is_multi_currency = self.paid_from_account_currency != ref_currency
if not (is_single_currency and reference_is_multi_currency):
return allocated_amount
allocated_amount = flt(
allocated_amount / ref_exchange_rate, self.precision("total_allocated_amount")
)
return allocated_amount
def set_status(self):
if self.docstatus == 2:
self.status = "Cancelled"
@@ -598,6 +692,28 @@ class PaymentEntry(AccountsController):
self.precision("base_received_amount"),
)
def calculate_base_allocated_amount_for_reference(self, d) -> float:
base_allocated_amount = 0
if d.reference_doctype in frappe.get_hooks("advance_payment_doctypes"):
# When referencing Sales/Purchase Order, use the source/target exchange rate depending on payment type.
# This is so there are no Exchange Gain/Loss generated for such doctypes
exchange_rate = 1
if self.payment_type == "Receive":
exchange_rate = self.source_exchange_rate
elif self.payment_type == "Pay":
exchange_rate = self.target_exchange_rate
base_allocated_amount += flt(
flt(d.allocated_amount) * flt(exchange_rate), self.precision("base_paid_amount")
)
else:
base_allocated_amount += flt(
flt(d.allocated_amount) * flt(d.exchange_rate), self.precision("base_paid_amount")
)
return base_allocated_amount
def set_total_allocated_amount(self):
if self.payment_type == "Internal Transfer":
return
@@ -606,9 +722,7 @@ class PaymentEntry(AccountsController):
for d in self.get("references"):
if d.allocated_amount:
total_allocated_amount += flt(d.allocated_amount)
base_total_allocated_amount += flt(
flt(d.allocated_amount) * flt(d.exchange_rate), self.precision("base_paid_amount")
)
base_total_allocated_amount += self.calculate_base_allocated_amount_for_reference(d)
self.total_allocated_amount = abs(total_allocated_amount)
self.base_total_allocated_amount = abs(base_total_allocated_amount)
@@ -622,7 +736,7 @@ class PaymentEntry(AccountsController):
self.payment_type == "Receive"
and self.base_total_allocated_amount < self.base_received_amount + total_deductions
and self.total_allocated_amount
< self.paid_amount + (total_deductions / self.source_exchange_rate)
< flt(self.paid_amount) + (total_deductions / self.source_exchange_rate)
):
self.unallocated_amount = (
self.base_received_amount + total_deductions - self.base_total_allocated_amount
@@ -632,7 +746,7 @@ class PaymentEntry(AccountsController):
self.payment_type == "Pay"
and self.base_total_allocated_amount < (self.base_paid_amount - total_deductions)
and self.total_allocated_amount
< self.received_amount + (total_deductions / self.target_exchange_rate)
< flt(self.received_amount) + (total_deductions / self.target_exchange_rate)
):
self.unallocated_amount = (
self.base_paid_amount - (total_deductions + self.base_total_allocated_amount)
@@ -684,35 +798,34 @@ class PaymentEntry(AccountsController):
)
def validate_payment_against_negative_invoice(self):
if (self.payment_type == "Pay" and self.party_type == "Customer") or (
self.payment_type == "Receive" and self.party_type == "Supplier"
if (self.payment_type != "Pay" or self.party_type != "Customer") and (
self.payment_type != "Receive" or self.party_type != "Supplier"
):
return
total_negative_outstanding = sum(
abs(flt(d.outstanding_amount)) for d in self.get("references") if flt(d.outstanding_amount) < 0
total_negative_outstanding = sum(
abs(flt(d.outstanding_amount)) for d in self.get("references") if flt(d.outstanding_amount) < 0
)
paid_amount = self.paid_amount if self.payment_type == "Receive" else self.received_amount
additional_charges = sum(flt(d.amount) for d in self.deductions)
if not total_negative_outstanding:
if self.party_type == "Customer":
msg = _("Cannot pay to Customer without any negative outstanding invoice")
else:
msg = _("Cannot receive from Supplier without any negative outstanding invoice")
frappe.throw(msg, InvalidPaymentEntry)
elif paid_amount - additional_charges > total_negative_outstanding:
frappe.throw(
_("Paid Amount cannot be greater than total negative outstanding amount {0}").format(
total_negative_outstanding
),
InvalidPaymentEntry,
)
paid_amount = self.paid_amount if self.payment_type == "Receive" else self.received_amount
additional_charges = sum([flt(d.amount) for d in self.deductions])
if not total_negative_outstanding:
frappe.throw(
_("Cannot {0} {1} {2} without any negative outstanding invoice").format(
_(self.payment_type),
(_("to") if self.party_type == "Customer" else _("from")),
self.party_type,
),
InvalidPaymentEntry,
)
elif paid_amount - additional_charges > total_negative_outstanding:
frappe.throw(
_("Paid Amount cannot be greater than total negative outstanding amount {0}").format(
total_negative_outstanding
),
InvalidPaymentEntry,
)
def set_title(self):
if frappe.flags.in_import and self.title:
# do not set title dynamically if title exists during data import.
@@ -826,9 +939,7 @@ class PaymentEntry(AccountsController):
}
)
allocated_amount_in_company_currency = flt(
flt(d.allocated_amount) * flt(d.exchange_rate), self.precision("paid_amount")
)
allocated_amount_in_company_currency = self.calculate_base_allocated_amount_for_reference(d)
gle.update(
{
@@ -1188,6 +1299,7 @@ def get_outstanding_reference_documents(args):
ple = qb.DocType("Payment Ledger Entry")
common_filter = []
accounting_dimensions_filter = []
posting_and_due_date = []
# confirm that Supplier is not blocked
@@ -1217,7 +1329,7 @@ def get_outstanding_reference_documents(args):
# Add cost center condition
if args.get("cost_center"):
condition += " and cost_center='%s'" % args.get("cost_center")
common_filter.append(ple.cost_center == args.get("cost_center"))
accounting_dimensions_filter.append(ple.cost_center == args.get("cost_center"))
date_fields_dict = {
"posting_date": ["from_posting_date", "to_posting_date"],
@@ -1243,6 +1355,7 @@ def get_outstanding_reference_documents(args):
posting_date=posting_and_due_date,
min_outstanding=args.get("outstanding_amt_greater_than"),
max_outstanding=args.get("outstanding_amt_less_than"),
accounting_dimensions=accounting_dimensions_filter,
)
outstanding_invoices = split_invoices_based_on_payment_terms(outstanding_invoices)
@@ -1374,7 +1487,7 @@ def get_orders_to_be_billed(
if voucher_type:
doc = frappe.get_doc({"doctype": voucher_type})
condition = ""
if doc and hasattr(doc, "cost_center"):
if doc and hasattr(doc, "cost_center") and doc.cost_center:
condition = " and cost_center='%s'" % cost_center
orders = []
@@ -1420,9 +1533,15 @@ def get_orders_to_be_billed(
order_list = []
for d in orders:
if not (
flt(d.outstanding_amount) >= flt(filters.get("outstanding_amt_greater_than"))
and flt(d.outstanding_amount) <= flt(filters.get("outstanding_amt_less_than"))
if (
filters
and filters.get("outstanding_amt_greater_than")
and filters.get("outstanding_amt_less_than")
and not (
flt(filters.get("outstanding_amt_greater_than"))
<= flt(d.outstanding_amount)
<= flt(filters.get("outstanding_amt_less_than"))
)
):
continue
@@ -1543,17 +1662,7 @@ def get_account_details(account, date, cost_center=None):
@frappe.whitelist()
def get_company_defaults(company):
fields = ["write_off_account", "exchange_gain_loss_account", "cost_center"]
ret = frappe.get_cached_value("Company", company, fields, as_dict=1)
for fieldname in fields:
if not ret[fieldname]:
frappe.throw(
_("Please set default {0} in Company {1}").format(
frappe.get_meta("Company").get_label(fieldname), company
)
)
return ret
return frappe.get_cached_value("Company", company, fields, as_dict=1)
def get_outstanding_on_journal_entry(name):
@@ -1635,11 +1744,21 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
@frappe.whitelist()
def get_payment_entry(
dt, dn, party_amount=None, bank_account=None, bank_amount=None, party_type=None, payment_type=None
dt,
dn,
party_amount=None,
bank_account=None,
bank_amount=None,
party_type=None,
payment_type=None,
reference_date=None,
):
reference_doc = None
doc = frappe.get_doc(dt, dn)
if dt in ("Sales Order", "Purchase Order") and flt(doc.per_billed, 2) > 0:
over_billing_allowance = frappe.db.get_single_value("Accounts Settings", "over_billing_allowance")
if dt in ("Sales Order", "Purchase Order") and flt(doc.per_billed, 2) >= (
100.0 + over_billing_allowance
):
frappe.throw(_("Can only make payment against unbilled {0}").format(dt))
if not party_type:
@@ -1658,12 +1777,20 @@ def get_payment_entry(
# bank or cash
bank = get_bank_cash_account(doc, bank_account)
# if default bank or cash account is not set in company master and party has default company bank account, fetch it
if party_type in ["Customer", "Supplier"] and not bank:
party_bank_account = get_party_bank_account(party_type, doc.get(scrub(party_type)))
if party_bank_account:
account = frappe.db.get_value("Bank Account", party_bank_account, "account")
bank = get_bank_cash_account(doc, account)
paid_amount, received_amount = set_paid_amount_and_received_amount(
dt, party_account_currency, bank, outstanding_amount, payment_type, bank_amount, doc
)
paid_amount, received_amount, discount_amount = apply_early_payment_discount(
paid_amount, received_amount, doc
reference_date = getdate(reference_date)
paid_amount, received_amount, discount_amount, valid_discounts = apply_early_payment_discount(
paid_amount, received_amount, doc, party_account_currency, reference_date
)
pe = frappe.new_doc("Payment Entry")
@@ -1671,6 +1798,7 @@ def get_payment_entry(
pe.company = doc.company
pe.cost_center = doc.get("cost_center")
pe.posting_date = nowdate()
pe.reference_date = reference_date
pe.mode_of_payment = doc.get("mode_of_payment")
pe.party_type = party_type
pe.party = doc.get(scrub(party_type))
@@ -1704,14 +1832,19 @@ def get_payment_entry(
if doc.doctype == "Purchase Invoice" and doc.invoice_is_blocked():
frappe.msgprint(_("{0} is on hold till {1}").format(doc.name, doc.release_date))
else:
if doc.doctype in ("Sales Invoice", "Purchase Invoice") and frappe.get_cached_value(
if doc.doctype in (
"Sales Invoice",
"Purchase Invoice",
"Purchase Order",
"Sales Order",
) and frappe.get_cached_value(
"Payment Terms Template",
doc.payment_terms_template,
"allocate_payment_based_on_payment_terms",
):
for reference in get_reference_as_per_payment_terms(
doc.payment_schedule, dt, dn, doc, grand_total, outstanding_amount
doc.payment_schedule, dt, dn, doc, grand_total, outstanding_amount, party_account_currency
):
pe.append("references", reference)
else:
@@ -1756,24 +1889,40 @@ def get_payment_entry(
pe.setup_party_account_field()
pe.set_missing_values()
pe.set_missing_ref_details()
update_accounting_dimensions(pe, doc)
if party_account and bank:
pe.set_exchange_rate(ref_doc=reference_doc)
pe.set_amounts()
if discount_amount:
pe.set_gain_or_loss(
account_details={
"account": frappe.get_cached_value("Company", pe.company, "default_discount_account"),
"cost_center": pe.cost_center
or frappe.get_cached_value("Company", pe.company, "cost_center"),
"amount": discount_amount * (-1 if payment_type == "Pay" else 1),
}
base_total_discount_loss = 0
if frappe.db.get_single_value("Accounts Settings", "book_tax_discount_loss"):
base_total_discount_loss = split_early_payment_discount_loss(pe, doc, valid_discounts)
set_pending_discount_loss(
pe, doc, discount_amount, base_total_discount_loss, party_account_currency
)
pe.set_difference_amount()
pe.set_difference_amount()
return pe
def update_accounting_dimensions(pe, doc):
"""
Updates accounting dimensions in Payment Entry based on the accounting dimensions in the reference document
"""
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
get_accounting_dimensions,
)
for dimension in get_accounting_dimensions():
pe.set(dimension, doc.get(dimension))
def get_bank_cash_account(doc, bank_account):
bank = get_default_bank_cash_account(
doc.company, "Bank", mode_of_payment=doc.get("mode_of_payment"), account=bank_account
@@ -1851,37 +2000,53 @@ def set_paid_amount_and_received_amount(
paid_amount = received_amount = 0
if party_account_currency == bank.account_currency:
paid_amount = received_amount = abs(outstanding_amount)
elif payment_type == "Receive":
paid_amount = abs(outstanding_amount)
if bank_amount:
received_amount = bank_amount
else:
received_amount = paid_amount * doc.get("conversion_rate", 1)
else:
received_amount = abs(outstanding_amount)
if bank_amount:
paid_amount = bank_amount
company_currency = frappe.get_cached_value("Company", doc.get("company"), "default_currency")
if payment_type == "Receive":
paid_amount = abs(outstanding_amount)
if bank_amount:
received_amount = bank_amount
else:
if company_currency != bank.account_currency:
received_amount = paid_amount / doc.get("conversion_rate", 1)
else:
received_amount = paid_amount * doc.get("conversion_rate", 1)
else:
# if party account currency and bank currency is different then populate paid amount as well
paid_amount = received_amount * doc.get("conversion_rate", 1)
received_amount = abs(outstanding_amount)
if bank_amount:
paid_amount = bank_amount
else:
if company_currency != bank.account_currency:
paid_amount = received_amount / doc.get("conversion_rate", 1)
else:
# if party account currency and bank currency is different then populate paid amount as well
paid_amount = received_amount * doc.get("conversion_rate", 1)
return paid_amount, received_amount
def apply_early_payment_discount(paid_amount, received_amount, doc):
def apply_early_payment_discount(
paid_amount, received_amount, doc, party_account_currency, reference_date
):
total_discount = 0
valid_discounts = []
eligible_for_payments = ["Sales Order", "Sales Invoice", "Purchase Order", "Purchase Invoice"]
has_payment_schedule = hasattr(doc, "payment_schedule") and doc.payment_schedule
is_multi_currency = party_account_currency != doc.company_currency
if doc.doctype in eligible_for_payments and has_payment_schedule:
for term in doc.payment_schedule:
if not term.discounted_amount and term.discount and getdate(nowdate()) <= term.discount_date:
if not term.discounted_amount and term.discount and reference_date <= term.discount_date:
if term.discount_type == "Percentage":
discount_amount = flt(doc.get("grand_total")) * (term.discount / 100)
grand_total = doc.get("grand_total") if is_multi_currency else doc.get("base_grand_total")
discount_amount = flt(grand_total) * (term.discount / 100)
else:
discount_amount = term.discount
discount_amount_in_foreign_currency = discount_amount * doc.get("conversion_rate", 1)
# if accounting is done in the same currency, paid_amount = received_amount
conversion_rate = doc.get("conversion_rate", 1) if is_multi_currency else 1
discount_amount_in_foreign_currency = discount_amount * conversion_rate
if doc.doctype == "Sales Invoice":
paid_amount -= discount_amount
@@ -1890,23 +2055,151 @@ def apply_early_payment_discount(paid_amount, received_amount, doc):
received_amount -= discount_amount
paid_amount -= discount_amount_in_foreign_currency
valid_discounts.append({"type": term.discount_type, "discount": term.discount})
total_discount += discount_amount
if total_discount:
money = frappe.utils.fmt_money(total_discount, currency=doc.get("currency"))
currency = doc.get("currency") if is_multi_currency else doc.company_currency
money = frappe.utils.fmt_money(total_discount, currency=currency)
frappe.msgprint(_("Discount of {} applied as per Payment Term").format(money), alert=1)
return paid_amount, received_amount, total_discount
return paid_amount, received_amount, total_discount, valid_discounts
def set_pending_discount_loss(
pe, doc, discount_amount, base_total_discount_loss, party_account_currency
):
# If multi-currency, get base discount amount to adjust with base currency deductions/losses
if party_account_currency != doc.company_currency:
discount_amount = discount_amount * doc.get("conversion_rate", 1)
# Avoid considering miniscule losses
discount_amount = flt(discount_amount - base_total_discount_loss, doc.precision("grand_total"))
# Set base discount amount (discount loss/pending rounding loss) in deductions
if discount_amount > 0.0:
positive_negative = -1 if pe.payment_type == "Pay" else 1
# If tax loss booking is enabled, pending loss will be rounding loss.
# Otherwise it will be the total discount loss.
book_tax_loss = frappe.db.get_single_value("Accounts Settings", "book_tax_discount_loss")
account_type = "round_off_account" if book_tax_loss else "default_discount_account"
pe.set_gain_or_loss(
account_details={
"account": frappe.get_cached_value("Company", pe.company, account_type),
"cost_center": pe.cost_center or frappe.get_cached_value("Company", pe.company, "cost_center"),
"amount": discount_amount * positive_negative,
}
)
def split_early_payment_discount_loss(pe, doc, valid_discounts) -> float:
"""Split early payment discount into Income Loss & Tax Loss."""
total_discount_percent = get_total_discount_percent(doc, valid_discounts)
if not total_discount_percent:
return 0.0
base_loss_on_income = add_income_discount_loss(pe, doc, total_discount_percent)
base_loss_on_taxes = add_tax_discount_loss(pe, doc, total_discount_percent)
# Round off total loss rather than individual losses to reduce rounding error
return flt(base_loss_on_income + base_loss_on_taxes, doc.precision("grand_total"))
def get_total_discount_percent(doc, valid_discounts) -> float:
"""Get total percentage and amount discount applied as a percentage."""
total_discount_percent = (
sum(
discount.get("discount") for discount in valid_discounts if discount.get("type") == "Percentage"
)
or 0.0
)
# Operate in percentages only as it makes the income & tax split easier
total_discount_amount = (
sum(discount.get("discount") for discount in valid_discounts if discount.get("type") == "Amount")
or 0.0
)
if total_discount_amount:
discount_percentage = (total_discount_amount / doc.get("grand_total")) * 100
total_discount_percent += discount_percentage
return total_discount_percent
return total_discount_percent
def add_income_discount_loss(pe, doc, total_discount_percent) -> float:
"""Add loss on income discount in base currency."""
precision = doc.precision("total")
base_loss_on_income = doc.get("base_total") * (total_discount_percent / 100)
pe.append(
"deductions",
{
"account": frappe.get_cached_value("Company", pe.company, "default_discount_account"),
"cost_center": pe.cost_center or frappe.get_cached_value("Company", pe.company, "cost_center"),
"amount": flt(base_loss_on_income, precision),
},
)
return base_loss_on_income # Return loss without rounding
def add_tax_discount_loss(pe, doc, total_discount_percentage) -> float:
"""Add loss on tax discount in base currency."""
tax_discount_loss = {}
base_total_tax_loss = 0
precision = doc.precision("tax_amount_after_discount_amount", "taxes")
# The same account head could be used more than once
for tax in doc.get("taxes", []):
base_tax_loss = tax.get("base_tax_amount_after_discount_amount") * (
total_discount_percentage / 100
)
account = tax.get("account_head")
if not tax_discount_loss.get(account):
tax_discount_loss[account] = base_tax_loss
else:
tax_discount_loss[account] += base_tax_loss
for account, loss in tax_discount_loss.items():
base_total_tax_loss += loss
if loss == 0.0:
continue
pe.append(
"deductions",
{
"account": account,
"cost_center": pe.cost_center or frappe.get_cached_value("Company", pe.company, "cost_center"),
"amount": flt(loss, precision),
},
)
return base_total_tax_loss # Return loss without rounding
def get_reference_as_per_payment_terms(
payment_schedule, dt, dn, doc, grand_total, outstanding_amount
payment_schedule, dt, dn, doc, grand_total, outstanding_amount, party_account_currency
):
references = []
is_multi_currency_acc = (doc.currency != doc.company_currency) and (
party_account_currency != doc.company_currency
)
for payment_term in payment_schedule:
payment_term_outstanding = flt(
payment_term.payment_amount - payment_term.paid_amount, payment_term.precision("payment_amount")
)
if not is_multi_currency_acc:
# If accounting is done in company currency for multi-currency transaction
payment_term_outstanding = flt(
payment_term_outstanding * doc.get("conversion_rate"), payment_term.precision("payment_amount")
)
if payment_term_outstanding:
references.append(

View File

@@ -5,7 +5,7 @@ import unittest
import frappe
from frappe import qb
from frappe.tests.utils import FrappeTestCase
from frappe.tests.utils import FrappeTestCase, change_settings
from frappe.utils import flt, nowdate
from erpnext.accounts.doctype.payment_entry.payment_entry import (
@@ -51,6 +51,38 @@ class TestPaymentEntry(FrappeTestCase):
so_advance_paid = frappe.db.get_value("Sales Order", so.name, "advance_paid")
self.assertEqual(so_advance_paid, 0)
def test_payment_against_sales_order_usd_to_inr(self):
so = make_sales_order(
customer="_Test Customer USD", currency="USD", qty=1, rate=100, do_not_submit=True
)
so.conversion_rate = 50
so.submit()
pe = get_payment_entry("Sales Order", so.name)
pe.source_exchange_rate = 55
pe.received_amount = 5500
pe.insert()
pe.submit()
# there should be no difference amount
pe.reload()
self.assertEqual(pe.difference_amount, 0)
self.assertEqual(pe.deductions, [])
expected_gle = dict(
(d[0], d)
for d in [["_Test Receivable USD - _TC", 0, 5500, so.name], ["Cash - _TC", 5500.0, 0, None]]
)
self.validate_gl_entries(pe.name, expected_gle)
so_advance_paid = frappe.db.get_value("Sales Order", so.name, "advance_paid")
self.assertEqual(so_advance_paid, 100)
pe.cancel()
so_advance_paid = frappe.db.get_value("Sales Order", so.name, "advance_paid")
self.assertEqual(so_advance_paid, 0)
def test_payment_entry_for_blocked_supplier_invoice(self):
supplier = frappe.get_doc("Supplier", "_Test Supplier")
supplier.on_hold = 1
@@ -256,10 +288,25 @@ class TestPaymentEntry(FrappeTestCase):
},
)
si.save()
si.submit()
frappe.db.set_single_value("Accounts Settings", "book_tax_discount_loss", 1)
pe_with_tax_loss = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Cash - _TC")
self.assertEqual(pe_with_tax_loss.references[0].payment_term, "30 Credit Days with 10% Discount")
self.assertEqual(pe_with_tax_loss.references[0].allocated_amount, 236.0)
self.assertEqual(pe_with_tax_loss.paid_amount, 212.4)
self.assertEqual(pe_with_tax_loss.deductions[0].amount, 20.0) # Loss on Income
self.assertEqual(pe_with_tax_loss.deductions[1].amount, 3.6) # Loss on Tax
self.assertEqual(pe_with_tax_loss.deductions[1].account, "_Test Account Service Tax - _TC")
frappe.db.set_single_value("Accounts Settings", "book_tax_discount_loss", 0)
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Cash - _TC")
self.assertEqual(pe.references[0].allocated_amount, 236.0)
self.assertEqual(pe.paid_amount, 212.4)
self.assertEqual(pe.deductions[0].amount, 23.6)
pe.submit()
si.load_from_db()
@@ -269,6 +316,190 @@ class TestPaymentEntry(FrappeTestCase):
self.assertEqual(si.payment_schedule[0].outstanding, 0)
self.assertEqual(si.payment_schedule[0].discounted_amount, 23.6)
def test_payment_entry_against_payment_terms_with_discount_amount(self):
si = create_sales_invoice(do_not_save=1, qty=1, rate=200)
si.payment_terms_template = "Test Discount Amount Template"
create_payment_terms_template_with_discount(
name="30 Credit Days with Rs.50 Discount",
discount_type="Amount",
discount=50,
template_name="Test Discount Amount Template",
)
frappe.db.set_value("Company", si.company, "default_discount_account", "Write Off - _TC")
si.append(
"taxes",
{
"charge_type": "On Net Total",
"account_head": "_Test Account Service Tax - _TC",
"cost_center": "_Test Cost Center - _TC",
"description": "Service Tax",
"rate": 18,
},
)
si.save()
si.submit()
# Set reference date past discount cut off date
pe_1 = get_payment_entry(
"Sales Invoice",
si.name,
bank_account="_Test Cash - _TC",
reference_date=frappe.utils.add_days(si.posting_date, 2),
)
self.assertEqual(pe_1.paid_amount, 236.0) # discount not applied
# Test if tax loss is booked on enabling configuration
frappe.db.set_single_value("Accounts Settings", "book_tax_discount_loss", 1)
pe_with_tax_loss = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Cash - _TC")
self.assertEqual(pe_with_tax_loss.deductions[0].amount, 42.37) # Loss on Income
self.assertEqual(pe_with_tax_loss.deductions[1].amount, 7.63) # Loss on Tax
self.assertEqual(pe_with_tax_loss.deductions[1].account, "_Test Account Service Tax - _TC")
frappe.db.set_single_value("Accounts Settings", "book_tax_discount_loss", 0)
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Cash - _TC")
self.assertEqual(pe.references[0].allocated_amount, 236.0)
self.assertEqual(pe.paid_amount, 186)
self.assertEqual(pe.deductions[0].amount, 50.0)
pe.submit()
si.load_from_db()
self.assertEqual(si.payment_schedule[0].payment_amount, 236.0)
self.assertEqual(si.payment_schedule[0].paid_amount, 186)
self.assertEqual(si.payment_schedule[0].outstanding, 0)
self.assertEqual(si.payment_schedule[0].discounted_amount, 50)
@change_settings(
"Accounts Settings",
{
"allow_multi_currency_invoices_against_single_party_account": 1,
"book_tax_discount_loss": 1,
},
)
def test_payment_entry_multicurrency_si_with_base_currency_accounting_early_payment_discount(
self,
):
"""
1. Multi-currency SI with single currency accounting (company currency)
2. PE with early payment discount
3. Test if Paid Amount is calculated in company currency
4. Test if deductions are calculated in company currency
SI is in USD to document agreed amounts that are in USD, but the accounting is in base currency.
"""
si = create_sales_invoice(
customer="_Test Customer",
currency="USD",
conversion_rate=50,
do_not_save=1,
)
create_payment_terms_template_with_discount()
si.payment_terms_template = "Test Discount Template"
frappe.db.set_value("Company", si.company, "default_discount_account", "Write Off - _TC")
si.save()
si.submit()
pe = get_payment_entry(
"Sales Invoice",
si.name,
bank_account="_Test Bank - _TC",
)
pe.reference_no = si.name
pe.reference_date = nowdate()
# Early payment discount loss on income
self.assertEqual(pe.paid_amount, 4500.0) # Amount in company currency
self.assertEqual(pe.received_amount, 4500.0)
self.assertEqual(pe.deductions[0].amount, 500.0)
self.assertEqual(pe.deductions[0].account, "Write Off - _TC")
self.assertEqual(pe.difference_amount, 0.0)
pe.insert()
pe.submit()
expected_gle = dict(
(d[0], d)
for d in [
["Debtors - _TC", 0, 5000, si.name],
["_Test Bank - _TC", 4500, 0, None],
["Write Off - _TC", 500.0, 0, None],
]
)
self.validate_gl_entries(pe.name, expected_gle)
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
self.assertEqual(outstanding_amount, 0)
def test_payment_entry_multicurrency_accounting_si_with_early_payment_discount(self):
"""
1. Multi-currency SI with multi-currency accounting
2. PE with early payment discount and also exchange loss
3. Test if Paid Amount is calculated in transaction currency
4. Test if deductions are calculated in base/company currency
5. Test if exchange loss is reflected in difference
"""
si = create_sales_invoice(
customer="_Test Customer USD",
debit_to="_Test Receivable USD - _TC",
currency="USD",
conversion_rate=50,
do_not_save=1,
)
create_payment_terms_template_with_discount()
si.payment_terms_template = "Test Discount Template"
frappe.db.set_value("Company", si.company, "default_discount_account", "Write Off - _TC")
si.save()
si.submit()
pe = get_payment_entry(
"Sales Invoice", si.name, bank_account="_Test Bank - _TC", bank_amount=4700
)
pe.reference_no = si.name
pe.reference_date = nowdate()
# Early payment discount loss on income
self.assertEqual(pe.paid_amount, 90.0)
self.assertEqual(pe.received_amount, 4200.0) # 5000 - 500 (discount) - 300 (exchange loss)
self.assertEqual(pe.deductions[0].amount, 500.0)
self.assertEqual(pe.deductions[0].account, "Write Off - _TC")
# Exchange loss
self.assertEqual(pe.difference_amount, 300.0)
pe.append(
"deductions",
{
"account": "_Test Exchange Gain/Loss - _TC",
"cost_center": "_Test Cost Center - _TC",
"amount": 300.0,
},
)
pe.insert()
pe.submit()
self.assertEqual(pe.difference_amount, 0.0)
expected_gle = dict(
(d[0], d)
for d in [
["_Test Receivable USD - _TC", 0, 5000, si.name],
["_Test Bank - _TC", 4200, 0, None],
["Write Off - _TC", 500.0, 0, None],
["_Test Exchange Gain/Loss - _TC", 300.0, 0, None],
]
)
self.validate_gl_entries(pe.name, expected_gle)
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
self.assertEqual(outstanding_amount, 0)
def test_payment_against_purchase_invoice_to_check_status(self):
pi = make_purchase_invoice(
supplier="_Test Supplier USD",
@@ -782,6 +1013,30 @@ class TestPaymentEntry(FrappeTestCase):
employee = make_employee("test_payment_entry@salary.com", company="_Test Company")
create_payment_entry(party_type="Employee", party=employee, save=True)
def test_duplicate_payment_entry_allocate_amount(self):
si = create_sales_invoice()
pe_draft = get_payment_entry("Sales Invoice", si.name)
pe_draft.insert()
pe = get_payment_entry("Sales Invoice", si.name)
pe.submit()
self.assertRaises(frappe.ValidationError, pe_draft.submit)
def test_duplicate_payment_entry_partial_allocate_amount(self):
si = create_sales_invoice()
pe_draft = get_payment_entry("Sales Invoice", si.name)
pe_draft.insert()
pe = get_payment_entry("Sales Invoice", si.name)
pe.received_amount = si.total / 2
pe.references[0].allocated_amount = si.total / 2
pe.submit()
self.assertRaises(frappe.ValidationError, pe_draft.submit)
def create_payment_entry(**args):
payment_entry = frappe.new_doc("Payment Entry")
@@ -839,24 +1094,27 @@ def create_payment_terms_template():
).insert()
def create_payment_terms_template_with_discount():
def create_payment_terms_template_with_discount(
name=None, discount_type=None, discount=None, template_name=None
):
create_payment_term(name or "30 Credit Days with 10% Discount")
template_name = template_name or "Test Discount Template"
create_payment_term("30 Credit Days with 10% Discount")
if not frappe.db.exists("Payment Terms Template", "Test Discount Template"):
payment_term_template = frappe.get_doc(
if not frappe.db.exists("Payment Terms Template", template_name):
frappe.get_doc(
{
"doctype": "Payment Terms Template",
"template_name": "Test Discount Template",
"template_name": template_name,
"allocate_payment_based_on_payment_terms": 1,
"terms": [
{
"doctype": "Payment Terms Template Detail",
"payment_term": "30 Credit Days with 10% Discount",
"payment_term": name or "30 Credit Days with 10% Discount",
"invoice_portion": 100,
"credit_days_based_on": "Day(s) after invoice date",
"credit_days": 2,
"discount": 10,
"discount_type": discount_type or "Percentage",
"discount": discount or 10,
"discount_validity_based_on": "Day(s) after invoice date",
"discount_validity": 1,
}

View File

@@ -3,6 +3,7 @@
"creation": "2016-06-15 15:56:30.815503",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"account",
"cost_center",
@@ -17,9 +18,7 @@
"in_list_view": 1,
"label": "Account",
"options": "Account",
"reqd": 1,
"show_days": 1,
"show_seconds": 1
"reqd": 1
},
{
"fieldname": "cost_center",
@@ -28,37 +27,30 @@
"label": "Cost Center",
"options": "Cost Center",
"print_hide": 1,
"reqd": 1,
"show_days": 1,
"show_seconds": 1
"reqd": 1
},
{
"fieldname": "amount",
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Amount",
"reqd": 1,
"show_days": 1,
"show_seconds": 1
"label": "Amount (Company Currency)",
"options": "Company:company:default_currency",
"reqd": 1
},
{
"fieldname": "column_break_2",
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1
"fieldtype": "Column Break"
},
{
"fieldname": "description",
"fieldtype": "Small Text",
"label": "Description",
"show_days": 1,
"show_seconds": 1
"label": "Description"
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2020-09-12 20:38:08.110674",
"modified": "2023-03-06 07:11:57.739619",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry Deduction",
@@ -66,5 +58,6 @@
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC"
"sort_order": "DESC",
"states": []
}

View File

@@ -25,7 +25,8 @@
"in_list_view": 1,
"label": "Type",
"options": "DocType",
"reqd": 1
"reqd": 1,
"search_index": 1
},
{
"columns": 2,
@@ -35,7 +36,8 @@
"in_list_view": 1,
"label": "Name",
"options": "reference_doctype",
"reqd": 1
"reqd": 1,
"search_index": 1
},
{
"fieldname": "due_date",
@@ -104,7 +106,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2021-09-26 17:06:55.597389",
"modified": "2022-12-12 12:31:44.919895",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry Reference",
@@ -113,5 +115,6 @@
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -3,6 +3,7 @@
frappe.ui.form.on('Payment Gateway Account', {
refresh(frm) {
erpnext.utils.check_payments_app();
if(!frm.doc.__islocal) {
frm.set_df_property('payment_gateway', 'read_only', 1);
}

View File

@@ -65,23 +65,49 @@ erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationCo
this.frm.add_custom_button(__('Get Unreconciled Entries'), () =>
this.frm.trigger("get_unreconciled_entries")
);
this.frm.change_custom_button_type('Get Unreconciled Entries', null, 'primary');
this.frm.change_custom_button_type(__('Get Unreconciled Entries'), null, 'primary');
}
if (this.frm.doc.invoices.length && this.frm.doc.payments.length) {
this.frm.add_custom_button(__('Allocate'), () =>
this.frm.trigger("allocate")
);
this.frm.change_custom_button_type('Allocate', null, 'primary');
this.frm.change_custom_button_type('Get Unreconciled Entries', null, 'default');
this.frm.change_custom_button_type(__('Allocate'), null, 'primary');
this.frm.change_custom_button_type(__('Get Unreconciled Entries'), null, 'default');
}
if (this.frm.doc.allocation.length) {
this.frm.add_custom_button(__('Reconcile'), () =>
this.frm.trigger("reconcile")
);
this.frm.change_custom_button_type('Reconcile', null, 'primary');
this.frm.change_custom_button_type('Get Unreconciled Entries', null, 'default');
this.frm.change_custom_button_type('Allocate', null, 'default');
this.frm.change_custom_button_type(__('Reconcile'), null, 'primary');
this.frm.change_custom_button_type(__('Get Unreconciled Entries'), null, 'default');
this.frm.change_custom_button_type(__('Allocate'), null, 'default');
}
// check for any running reconciliation jobs
if (this.frm.doc.receivable_payable_account) {
frappe.db.get_single_value("Accounts Settings", "auto_reconcile_payments").then((enabled) => {
if(enabled) {
this.frm.call({
'method': "erpnext.accounts.doctype.process_payment_reconciliation.process_payment_reconciliation.is_any_doc_running",
"args": {
for_filter: {
company: this.frm.doc.company,
party_type: this.frm.doc.party_type,
party: this.frm.doc.party,
receivable_payable_account: this.frm.doc.receivable_payable_account
}
}
}).then(r => {
if (r.message) {
let doc_link = frappe.utils.get_form_link("Process Payment Reconciliation", r.message, true);
let msg = __("Payment Reconciliation Job: {0} is running for this party. Can't reconcile now.", [doc_link]);
this.frm.dashboard.add_comment(msg, "yellow");
}
});
}
});
}
}
company() {
@@ -170,7 +196,7 @@ erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationCo
}
reconcile() {
var show_dialog = this.frm.doc.allocation.filter(d => d.difference_amount && !d.difference_account);
var show_dialog = this.frm.doc.allocation.filter(d => d.difference_amount);
if (show_dialog && show_dialog.length) {
@@ -179,8 +205,12 @@ erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationCo
title: __("Select Difference Account"),
fields: [
{
fieldname: "allocation", fieldtype: "Table", label: __("Allocation"),
data: this.data, in_place_edit: true,
fieldname: "allocation",
fieldtype: "Table",
label: __("Allocation"),
data: this.data,
in_place_edit: true,
cannot_add_rows: true,
get_data: () => {
return this.data;
},
@@ -218,6 +248,10 @@ erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationCo
read_only: 1
}]
},
{
fieldtype: 'HTML',
options: "<b> New Journal Entry will be posted for the difference amount </b>"
}
],
primary_action: () => {
const args = dialog.get_values()["allocation"];
@@ -234,7 +268,7 @@ erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationCo
});
this.frm.doc.allocation.forEach(d => {
if (d.difference_amount && !d.difference_account) {
if (d.difference_amount) {
dialog.fields_dict.allocation.df.data.push({
'docname': d.name,
'reference_name': d.reference_name,
@@ -264,4 +298,32 @@ erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationCo
}
};
frappe.ui.form.on('Payment Reconciliation Allocation', {
allocated_amount: function(frm, cdt, cdn) {
let row = locals[cdt][cdn];
// filter invoice
let invoice = frm.doc.invoices.filter((x) => (x.invoice_number == row.invoice_number));
// filter payment
let payment = frm.doc.payments.filter((x) => (x.reference_name == row.reference_name));
frm.call({
doc: frm.doc,
method: 'calculate_difference_on_allocation_change',
args: {
payment_entry: payment,
invoice: invoice,
allocated_amount: row.allocated_amount
},
callback: (r) => {
if (r.message) {
row.difference_amount = r.message;
frm.refresh();
}
}
});
}
});
extend_cscript(cur_frm.cscript, new erpnext.accounts.PaymentReconciliationController({frm: cur_frm}));

View File

@@ -6,15 +6,16 @@ import frappe
from frappe import _, msgprint, qb
from frappe.model.document import Document
from frappe.query_builder.custom import ConstantColumn
from frappe.query_builder.functions import IfNull
from frappe.utils import flt, getdate, nowdate, today
from frappe.utils import flt, get_link_to_form, getdate, nowdate, today
import erpnext
from erpnext.accounts.doctype.process_payment_reconciliation.process_payment_reconciliation import (
is_any_doc_running,
)
from erpnext.accounts.utils import (
QueryPaymentLedger,
get_outstanding_invoices,
reconcile_against_document,
update_reference_in_payment_entry,
)
from erpnext.controllers.accounts_controller import get_advance_payment_entries
@@ -23,6 +24,7 @@ class PaymentReconciliation(Document):
def __init__(self, *args, **kwargs):
super(PaymentReconciliation, self).__init__(*args, **kwargs)
self.common_filter_conditions = []
self.accounting_dimension_filter_conditions = []
self.ple_posting_date_filter = []
@frappe.whitelist()
@@ -69,6 +71,10 @@ class PaymentReconciliation(Document):
def get_jv_entries(self):
condition = self.get_conditions()
if self.get("cost_center"):
condition += f" and t2.cost_center = '{self.cost_center}' "
dr_or_cr = (
"credit_in_account_currency"
if erpnext.get_party_account_type(self.party_type) == "Receivable"
@@ -79,12 +85,13 @@ class PaymentReconciliation(Document):
"t2.against_account like %(bank_cash_account)s" if self.bank_cash_account else "1=1"
)
# 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,
{dr_or_cr} as amount, t2.is_advance, t2.exchange_rate,
t2.account_currency as currency
from
`tabJournal Entry` t1, `tabJournal Entry Account` t2
@@ -119,12 +126,29 @@ class PaymentReconciliation(Document):
return list(journal_entries)
def get_return_invoices(self):
voucher_type = "Sales Invoice" if self.party_type == "Customer" else "Purchase Invoice"
doc = qb.DocType(voucher_type)
self.return_invoices = (
qb.from_(doc)
.select(
ConstantColumn(voucher_type).as_("voucher_type"),
doc.name.as_("voucher_no"),
doc.return_against,
)
.where(
(doc.docstatus == 1)
& (doc[frappe.scrub(self.party_type)] == self.party)
& (doc.is_return == 1)
)
.run(as_dict=True)
)
def get_dr_or_cr_notes(self):
self.build_qb_filter_conditions(get_return_invoices=True)
ple = qb.DocType("Payment Ledger Entry")
voucher_type = "Sales Invoice" if self.party_type == "Customer" else "Purchase Invoice"
if erpnext.get_party_account_type(self.party_type) == "Receivable":
self.common_filter_conditions.append(ple.account_type == "Receivable")
@@ -132,19 +156,10 @@ class PaymentReconciliation(Document):
self.common_filter_conditions.append(ple.account_type == "Payable")
self.common_filter_conditions.append(ple.account == self.receivable_payable_account)
# get return invoices
doc = qb.DocType(voucher_type)
return_invoices = (
qb.from_(doc)
.select(ConstantColumn(voucher_type).as_("voucher_type"), doc.name.as_("voucher_no"))
.where(
(doc.docstatus == 1)
& (doc[frappe.scrub(self.party_type)] == self.party)
& (doc.is_return == 1)
& (IfNull(doc.return_against, "") == "")
)
.run(as_dict=True)
)
self.get_return_invoices()
return_invoices = [
x for x in self.return_invoices if x.return_against == None or x.return_against == ""
]
outstanding_dr_or_cr = []
if return_invoices:
@@ -193,8 +208,18 @@ class PaymentReconciliation(Document):
posting_date=self.ple_posting_date_filter,
min_outstanding=self.minimum_invoice_amount if self.minimum_invoice_amount else None,
max_outstanding=self.maximum_invoice_amount if self.maximum_invoice_amount else None,
accounting_dimensions=self.accounting_dimension_filter_conditions,
)
cr_dr_notes = (
[x.voucher_no for x in self.return_invoices]
if self.party_type in ["Customer", "Supplier"]
else []
)
# Filter out cr/dr notes from outstanding invoices list
# Happens when non-standalone cr/dr notes are linked with another invoice through journal entry
non_reconciled_invoices = [x for x in non_reconciled_invoices if x.voucher_no not in cr_dr_notes]
if self.invoice_limit:
non_reconciled_invoices = non_reconciled_invoices[: self.invoice_limit]
@@ -213,26 +238,38 @@ class PaymentReconciliation(Document):
inv.currency = entry.get("currency")
inv.outstanding_amount = flt(entry.get("outstanding_amount"))
def get_difference_amount(self, allocated_entry):
if allocated_entry.get("reference_type") != "Payment Entry":
return
def get_difference_amount(self, payment_entry, invoice, allocated_amount):
difference_amount = 0
if frappe.get_cached_value(
"Account", self.receivable_payable_account, "account_currency"
) != frappe.get_cached_value("Company", self.company, "default_currency"):
if invoice.get("exchange_rate") and payment_entry.get("exchange_rate", 1) != invoice.get(
"exchange_rate", 1
):
allocated_amount_in_ref_rate = payment_entry.get("exchange_rate", 1) * allocated_amount
allocated_amount_in_inv_rate = invoice.get("exchange_rate", 1) * allocated_amount
difference_amount = allocated_amount_in_ref_rate - allocated_amount_in_inv_rate
dr_or_cr = (
"credit_in_account_currency"
if erpnext.get_party_account_type(self.party_type) == "Receivable"
else "debit_in_account_currency"
return difference_amount
@frappe.whitelist()
def calculate_difference_on_allocation_change(self, payment_entry, invoice, allocated_amount):
invoice_exchange_map = self.get_invoice_exchange_map(invoice, payment_entry)
invoice[0]["exchange_rate"] = invoice_exchange_map.get(invoice[0].get("invoice_number"))
new_difference_amount = self.get_difference_amount(
payment_entry[0], invoice[0], allocated_amount
)
row = self.get_payment_details(allocated_entry, dr_or_cr)
doc = frappe.get_doc(allocated_entry.reference_type, allocated_entry.reference_name)
update_reference_in_payment_entry(row, doc, do_not_save=True)
return doc.difference_amount
return new_difference_amount
@frappe.whitelist()
def allocate_entries(self, args):
self.validate_entries()
invoice_exchange_map = self.get_invoice_exchange_map(args.get("invoices"), args.get("payments"))
default_exchange_gain_loss_account = frappe.get_cached_value(
"Company", self.company, "exchange_gain_loss_account"
)
entries = []
for pay in args.get("payments"):
pay.update({"unreconciled_amount": pay.get("amount")})
@@ -246,7 +283,13 @@ class PaymentReconciliation(Document):
inv["outstanding_amount"] = flt(inv.get("outstanding_amount")) - flt(pay.get("amount"))
pay["amount"] = 0
res.difference_amount = self.get_difference_amount(res)
inv["exchange_rate"] = invoice_exchange_map.get(inv.get("invoice_number"))
if pay.get("reference_type") in ["Sales Invoice", "Purchase Invoice"]:
pay["exchange_rate"] = invoice_exchange_map.get(pay.get("reference_name"))
res.difference_amount = self.get_difference_amount(pay, inv, res["allocated_amount"])
res.difference_account = default_exchange_gain_loss_account
res.exchange_rate = inv.get("exchange_rate")
if pay.get("amount") == 0:
entries.append(res)
@@ -276,12 +319,11 @@ class PaymentReconciliation(Document):
"amount": pay.get("amount"),
"allocated_amount": allocated_amount,
"difference_amount": pay.get("difference_amount"),
"currency": inv.get("currency"),
}
)
@frappe.whitelist()
def reconcile(self):
self.validate_allocation()
def reconcile_allocations(self, skip_ref_details_update_for_pe=False):
dr_or_cr = (
"credit_in_account_currency"
if erpnext.get_party_account_type(self.party_type) == "Receivable"
@@ -298,17 +340,95 @@ class PaymentReconciliation(Document):
else:
reconciled_entry = entry_list
reconciled_entry.append(self.get_payment_details(row, dr_or_cr))
payment_details = self.get_payment_details(row, dr_or_cr)
reconciled_entry.append(payment_details)
if payment_details.difference_amount:
self.make_difference_entry(payment_details)
if entry_list:
reconcile_against_document(entry_list)
reconcile_against_document(entry_list, skip_ref_details_update_for_pe)
if dr_or_cr_notes:
reconcile_dr_cr_note(dr_or_cr_notes, self.company)
@frappe.whitelist()
def reconcile(self):
if frappe.db.get_single_value("Accounts Settings", "auto_reconcile_payments"):
running_doc = is_any_doc_running(
dict(
company=self.company,
party_type=self.party_type,
party=self.party,
receivable_payable_account=self.receivable_payable_account,
)
)
if running_doc:
frappe.throw(
_("A Reconciliation Job {0} is running for the same filters. Cannot reconcile now").format(
get_link_to_form("Auto Reconcile", running_doc)
)
)
return
self.validate_allocation()
self.reconcile_allocations()
msgprint(_("Successfully Reconciled"))
self.get_unreconciled_entries()
def make_difference_entry(self, row):
journal_entry = frappe.new_doc("Journal Entry")
journal_entry.voucher_type = "Exchange Gain Or Loss"
journal_entry.company = self.company
journal_entry.posting_date = nowdate()
journal_entry.multi_currency = 1
party_account_currency = frappe.get_cached_value(
"Account", self.receivable_payable_account, "account_currency"
)
difference_account_currency = frappe.get_cached_value(
"Account", row.difference_account, "account_currency"
)
# Account Currency has balance
dr_or_cr = "debit" if self.party_type == "Customer" else "credit"
reverse_dr_or_cr = "debit" if dr_or_cr == "credit" else "credit"
journal_account = frappe._dict(
{
"account": self.receivable_payable_account,
"party_type": self.party_type,
"party": self.party,
"account_currency": party_account_currency,
"exchange_rate": 0,
"cost_center": erpnext.get_default_cost_center(self.company),
"reference_type": row.against_voucher_type,
"reference_name": row.against_voucher,
dr_or_cr: flt(row.difference_amount),
dr_or_cr + "_in_account_currency": 0,
}
)
journal_entry.append("accounts", journal_account)
journal_account = frappe._dict(
{
"account": row.difference_account,
"account_currency": difference_account_currency,
"exchange_rate": 1,
"cost_center": erpnext.get_default_cost_center(self.company),
reverse_dr_or_cr + "_in_account_currency": flt(row.difference_amount),
reverse_dr_or_cr: flt(row.difference_amount),
}
)
journal_entry.append("accounts", journal_account)
journal_entry.save()
journal_entry.submit()
def get_payment_details(self, row, dr_or_cr):
return frappe._dict(
{
@@ -318,6 +438,7 @@ class PaymentReconciliation(Document):
"against_voucher_type": row.get("invoice_type"),
"against_voucher": row.get("invoice_number"),
"account": self.receivable_payable_account,
"exchange_rate": row.get("exchange_rate"),
"party_type": self.party_type,
"party": self.party,
"is_advance": row.get("is_advance"),
@@ -342,6 +463,49 @@ class PaymentReconciliation(Document):
if not self.get("payments"):
frappe.throw(_("No records found in the Payments table"))
def get_invoice_exchange_map(self, invoices, payments):
sales_invoices = [
d.get("invoice_number") for d in invoices if d.get("invoice_type") == "Sales Invoice"
]
sales_invoices.extend(
[d.get("reference_name") for d in payments if d.get("reference_type") == "Sales Invoice"]
)
purchase_invoices = [
d.get("invoice_number") for d in invoices if d.get("invoice_type") == "Purchase Invoice"
]
purchase_invoices.extend(
[d.get("reference_name") for d in payments if d.get("reference_type") == "Purchase Invoice"]
)
invoice_exchange_map = frappe._dict()
if sales_invoices:
sales_invoice_map = frappe._dict(
frappe.db.get_all(
"Sales Invoice",
filters={"name": ("in", sales_invoices)},
fields=["name", "conversion_rate"],
as_list=1,
)
)
invoice_exchange_map.update(sales_invoice_map)
if purchase_invoices:
purchase_invoice_map = frappe._dict(
frappe.db.get_all(
"Purchase Invoice",
filters={"name": ("in", purchase_invoices)},
fields=["name", "conversion_rate"],
as_list=1,
)
)
invoice_exchange_map.update(purchase_invoice_map)
return invoice_exchange_map
def validate_allocation(self):
unreconciled_invoices = frappe._dict()
@@ -375,13 +539,14 @@ class PaymentReconciliation(Document):
def build_qb_filter_conditions(self, get_invoices=False, get_return_invoices=False):
self.common_filter_conditions.clear()
self.accounting_dimension_filter_conditions.clear()
self.ple_posting_date_filter.clear()
ple = qb.DocType("Payment Ledger Entry")
self.common_filter_conditions.append(ple.company == self.company)
if self.get("cost_center") and (get_invoices or get_return_invoices):
self.common_filter_conditions.append(ple.cost_center == self.cost_center)
self.accounting_dimension_filter_conditions.append(ple.cost_center == self.cost_center)
if get_invoices:
if self.from_invoice_date:

View File

@@ -5,9 +5,11 @@ import unittest
import frappe
from frappe import qb
from frappe.tests.utils import FrappeTestCase
from frappe.utils import add_days, nowdate
from frappe.tests.utils import FrappeTestCase, change_settings
from frappe.utils import add_days, flt, nowdate
from erpnext import get_default_cost_center
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
from erpnext.accounts.party import get_party_account
@@ -20,6 +22,7 @@ class TestPaymentReconciliation(FrappeTestCase):
self.create_item()
self.create_customer()
self.create_account()
self.create_cost_center()
self.clear_old_entries()
def tearDown(self):
@@ -72,33 +75,11 @@ class TestPaymentReconciliation(FrappeTestCase):
self.item = item if isinstance(item, str) else item.item_code
def create_customer(self):
if frappe.db.exists("Customer", "_Test PR Customer"):
self.customer = "_Test PR Customer"
else:
customer = frappe.new_doc("Customer")
customer.customer_name = "_Test PR Customer"
customer.type = "Individual"
customer.save()
self.customer = customer.name
if frappe.db.exists("Customer", "_Test PR Customer 2"):
self.customer2 = "_Test PR Customer 2"
else:
customer = frappe.new_doc("Customer")
customer.customer_name = "_Test PR Customer 2"
customer.type = "Individual"
customer.save()
self.customer2 = customer.name
if frappe.db.exists("Customer", "_Test PR Customer 3"):
self.customer3 = "_Test PR Customer 3"
else:
customer = frappe.new_doc("Customer")
customer.customer_name = "_Test PR Customer 3"
customer.type = "Individual"
customer.default_currency = "EUR"
customer.save()
self.customer3 = customer.name
self.customer = make_customer("_Test PR Customer")
self.customer2 = make_customer("_Test PR Customer 2")
self.customer3 = make_customer("_Test PR Customer 3", "EUR")
self.customer4 = make_customer("_Test PR Customer 4", "EUR")
self.customer5 = make_customer("_Test PR Customer 5", "EUR")
def create_account(self):
account_name = "Debtors EUR"
@@ -216,6 +197,22 @@ class TestPaymentReconciliation(FrappeTestCase):
)
return je
def create_cost_center(self):
# Setup cost center
cc_name = "Sub"
self.main_cc = frappe.get_doc("Cost Center", get_default_cost_center(self.company))
cc_exists = frappe.db.get_list("Cost Center", filters={"cost_center_name": cc_name})
if cc_exists:
self.sub_cc = frappe.get_doc("Cost Center", cc_exists[0].name)
else:
sub_cc = frappe.new_doc("Cost Center")
sub_cc.cost_center_name = "Sub"
sub_cc.parent_cost_center = self.main_cc.parent_cost_center
sub_cc.company = self.main_cc.company
self.sub_cc = sub_cc.save()
def test_filter_min_max(self):
# check filter condition minimum and maximum amount
self.create_sales_invoice(qty=1, rate=300)
@@ -352,6 +349,11 @@ class TestPaymentReconciliation(FrappeTestCase):
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}))
# Difference amount should not be calculated for base currency accounts
for row in pr.allocation:
self.assertEqual(flt(row.get("difference_amount")), 0.0)
pr.reconcile()
si.reload()
@@ -393,6 +395,11 @@ class TestPaymentReconciliation(FrappeTestCase):
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}))
# Difference amount should not be calculated for base currency accounts
for row in pr.allocation:
self.assertEqual(flt(row.get("difference_amount")), 0.0)
pr.reconcile()
# check PR tool output
@@ -417,6 +424,11 @@ class TestPaymentReconciliation(FrappeTestCase):
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}))
# Difference amount should not be calculated for base currency accounts
for row in pr.allocation:
self.assertEqual(flt(row.get("difference_amount")), 0.0)
pr.reconcile()
# assert outstanding
@@ -453,6 +465,11 @@ class TestPaymentReconciliation(FrappeTestCase):
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}))
# Difference amount should not be calculated for base currency accounts
for row in pr.allocation:
self.assertEqual(flt(row.get("difference_amount")), 0.0)
pr.reconcile()
self.assertEqual(pr.get("invoices"), [])
@@ -476,6 +493,11 @@ class TestPaymentReconciliation(FrappeTestCase):
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}))
# Cr Note and Invoice are of the same currency. There shouldn't any difference amount.
for row in pr.allocation:
self.assertEqual(flt(row.get("difference_amount")), 0.0)
pr.reconcile()
pr.get_unreconciled_entries()
@@ -509,6 +531,11 @@ class TestPaymentReconciliation(FrappeTestCase):
payments = [x.as_dict() for x in pr.get("payments")]
pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
pr.allocation[0].allocated_amount = allocated_amount
# Cr Note and Invoice are of the same currency. There shouldn't any difference amount.
for row in pr.allocation:
self.assertEqual(flt(row.get("difference_amount")), 0.0)
pr.reconcile()
# assert outstanding
@@ -578,3 +605,301 @@ class TestPaymentReconciliation(FrappeTestCase):
self.assertEqual(len(pr.payments), 1)
self.assertEqual(pr.payments[0].amount, amount)
self.assertEqual(pr.payments[0].currency, "EUR")
def test_difference_amount_via_journal_entry(self):
# Make Sale Invoice
si = self.create_sales_invoice(
qty=1, rate=100, posting_date=nowdate(), do_not_save=True, do_not_submit=True
)
si.customer = self.customer4
si.currency = "EUR"
si.conversion_rate = 85
si.debit_to = self.debtors_eur
si.save().submit()
# Make payment using Journal Entry
je1 = self.create_journal_entry("HDFC - _PR", self.debtors_eur, 100, nowdate())
je1.multi_currency = 1
je1.accounts[0].exchange_rate = 1
je1.accounts[0].credit_in_account_currency = 0
je1.accounts[0].credit = 0
je1.accounts[0].debit_in_account_currency = 8000
je1.accounts[0].debit = 8000
je1.accounts[1].party_type = "Customer"
je1.accounts[1].party = self.customer4
je1.accounts[1].exchange_rate = 80
je1.accounts[1].credit_in_account_currency = 100
je1.accounts[1].credit = 8000
je1.accounts[1].debit_in_account_currency = 0
je1.accounts[1].debit = 0
je1.save()
je1.submit()
je2 = self.create_journal_entry("HDFC - _PR", self.debtors_eur, 200, nowdate())
je2.multi_currency = 1
je2.accounts[0].exchange_rate = 1
je2.accounts[0].credit_in_account_currency = 0
je2.accounts[0].credit = 0
je2.accounts[0].debit_in_account_currency = 16000
je2.accounts[0].debit = 16000
je2.accounts[1].party_type = "Customer"
je2.accounts[1].party = self.customer4
je2.accounts[1].exchange_rate = 80
je2.accounts[1].credit_in_account_currency = 200
je1.accounts[1].credit = 16000
je1.accounts[1].debit_in_account_currency = 0
je1.accounts[1].debit = 0
je2.save()
je2.submit()
pr = self.create_payment_reconciliation()
pr.party = self.customer4
pr.receivable_payable_account = self.debtors_eur
pr.get_unreconciled_entries()
self.assertEqual(len(pr.invoices), 1)
self.assertEqual(len(pr.payments), 2)
# Test exact payment allocation
invoices = [x.as_dict() for x in pr.invoices]
payments = [pr.payments[0].as_dict()]
pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
self.assertEqual(pr.allocation[0].allocated_amount, 100)
self.assertEqual(pr.allocation[0].difference_amount, -500)
# Test partial payment allocation (with excess payment entry)
pr.set("allocation", [])
pr.get_unreconciled_entries()
invoices = [x.as_dict() for x in pr.invoices]
payments = [pr.payments[1].as_dict()]
pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
pr.allocation[0].difference_account = "Exchange Gain/Loss - _PR"
self.assertEqual(pr.allocation[0].allocated_amount, 100)
self.assertEqual(pr.allocation[0].difference_amount, -500)
# Check if difference journal entry gets generated for difference amount after reconciliation
pr.reconcile()
total_debit_amount = frappe.db.get_all(
"Journal Entry Account",
{"account": self.debtors_eur, "docstatus": 1, "reference_name": si.name},
"sum(debit) as amount",
group_by="reference_name",
)[0].amount
self.assertEqual(flt(total_debit_amount, 2), -500)
def test_difference_amount_via_payment_entry(self):
# Make Sale Invoice
si = self.create_sales_invoice(
qty=1, rate=100, posting_date=nowdate(), do_not_save=True, do_not_submit=True
)
si.customer = self.customer5
si.currency = "EUR"
si.conversion_rate = 85
si.debit_to = self.debtors_eur
si.save().submit()
# Make payment using Payment Entry
pe1 = create_payment_entry(
company=self.company,
payment_type="Receive",
party_type="Customer",
party=self.customer5,
paid_from=self.debtors_eur,
paid_to=self.bank,
paid_amount=100,
)
pe1.source_exchange_rate = 80
pe1.received_amount = 8000
pe1.save()
pe1.submit()
pe2 = create_payment_entry(
company=self.company,
payment_type="Receive",
party_type="Customer",
party=self.customer5,
paid_from=self.debtors_eur,
paid_to=self.bank,
paid_amount=200,
)
pe2.source_exchange_rate = 80
pe2.received_amount = 16000
pe2.save()
pe2.submit()
pr = self.create_payment_reconciliation()
pr.party = self.customer5
pr.receivable_payable_account = self.debtors_eur
pr.get_unreconciled_entries()
self.assertEqual(len(pr.invoices), 1)
self.assertEqual(len(pr.payments), 2)
invoices = [x.as_dict() for x in pr.invoices]
payments = [pr.payments[0].as_dict()]
pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
self.assertEqual(pr.allocation[0].allocated_amount, 100)
self.assertEqual(pr.allocation[0].difference_amount, -500)
pr.set("allocation", [])
pr.get_unreconciled_entries()
invoices = [x.as_dict() for x in pr.invoices]
payments = [pr.payments[1].as_dict()]
pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
self.assertEqual(pr.allocation[0].allocated_amount, 100)
self.assertEqual(pr.allocation[0].difference_amount, -500)
def test_differing_cost_center_on_invoice_and_payment(self):
"""
Cost Center filter should not affect outstanding amount calculation
"""
si = self.create_sales_invoice(qty=1, rate=100, do_not_submit=True)
si.cost_center = self.main_cc.name
si.submit()
pr = get_payment_entry(si.doctype, si.name)
pr.cost_center = self.sub_cc.name
pr = pr.save().submit()
pr = self.create_payment_reconciliation()
pr.cost_center = self.main_cc.name
pr.get_unreconciled_entries()
# check PR tool output
self.assertEqual(len(pr.get("invoices")), 0)
self.assertEqual(len(pr.get("payments")), 0)
def test_cost_center_filter_on_vouchers(self):
"""
Test Cost Center filter is applied on Invoices, Payment Entries and Journals
"""
transaction_date = nowdate()
rate = 100
# 'Main - PR' Cost Center
si1 = self.create_sales_invoice(
qty=1, rate=rate, posting_date=transaction_date, do_not_submit=True
)
si1.cost_center = self.main_cc.name
si1.submit()
pe1 = self.create_payment_entry(posting_date=transaction_date, amount=rate)
pe1.cost_center = self.main_cc.name
pe1 = pe1.save().submit()
je1 = self.create_journal_entry(self.bank, self.debit_to, 100, transaction_date)
je1.accounts[0].cost_center = self.main_cc.name
je1.accounts[1].cost_center = self.main_cc.name
je1.accounts[1].party_type = "Customer"
je1.accounts[1].party = self.customer
je1 = je1.save().submit()
# 'Sub - PR' Cost Center
si2 = self.create_sales_invoice(
qty=1, rate=rate, posting_date=transaction_date, do_not_submit=True
)
si2.cost_center = self.sub_cc.name
si2.submit()
pe2 = self.create_payment_entry(posting_date=transaction_date, amount=rate)
pe2.cost_center = self.sub_cc.name
pe2 = pe2.save().submit()
je2 = self.create_journal_entry(self.bank, self.debit_to, 100, transaction_date)
je2.accounts[0].cost_center = self.sub_cc.name
je2.accounts[1].cost_center = self.sub_cc.name
je2.accounts[1].party_type = "Customer"
je2.accounts[1].party = self.customer
je2 = je2.save().submit()
pr = self.create_payment_reconciliation()
pr.cost_center = self.main_cc.name
pr.get_unreconciled_entries()
# check PR tool output
self.assertEqual(len(pr.get("invoices")), 1)
self.assertEqual(pr.get("invoices")[0].get("invoice_number"), si1.name)
self.assertEqual(len(pr.get("payments")), 2)
payment_vouchers = [x.get("reference_name") for x in pr.get("payments")]
self.assertCountEqual(payment_vouchers, [pe1.name, je1.name])
# Change cost center
pr.cost_center = self.sub_cc.name
pr.get_unreconciled_entries()
# check PR tool output
self.assertEqual(len(pr.get("invoices")), 1)
self.assertEqual(pr.get("invoices")[0].get("invoice_number"), si2.name)
self.assertEqual(len(pr.get("payments")), 2)
payment_vouchers = [x.get("reference_name") for x in pr.get("payments")]
self.assertCountEqual(payment_vouchers, [je2.name, pe2.name])
@change_settings(
"Accounts Settings",
{
"allow_multi_currency_invoices_against_single_party_account": 1,
},
)
def test_no_difference_amount_for_base_currency_accounts(self):
# Make Sale Invoice
si = self.create_sales_invoice(
qty=1, rate=1, posting_date=nowdate(), do_not_save=True, do_not_submit=True
)
si.customer = self.customer
si.currency = "EUR"
si.conversion_rate = 85
si.debit_to = self.debit_to
si.save().submit()
# Make payment using Payment Entry
pe1 = create_payment_entry(
company=self.company,
payment_type="Receive",
party_type="Customer",
party=self.customer,
paid_from=self.debit_to,
paid_to=self.bank,
paid_amount=100,
)
pe1.save()
pe1.submit()
pr = self.create_payment_reconciliation()
pr.party = self.customer
pr.receivable_payable_account = self.debit_to
pr.get_unreconciled_entries()
self.assertEqual(len(pr.invoices), 1)
self.assertEqual(len(pr.payments), 1)
invoices = [x.as_dict() for x in pr.invoices]
payments = [pr.payments[0].as_dict()]
pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
self.assertEqual(pr.allocation[0].allocated_amount, 85)
self.assertEqual(pr.allocation[0].difference_amount, 0)
def make_customer(customer_name, currency=None):
if not frappe.db.exists("Customer", customer_name):
customer = frappe.new_doc("Customer")
customer.customer_name = customer_name
customer.type = "Individual"
if currency:
customer.default_currency = currency
customer.save()
return customer.name
else:
return customer_name

View File

@@ -20,7 +20,9 @@
"section_break_5",
"difference_amount",
"column_break_7",
"difference_account"
"difference_account",
"exchange_rate",
"currency"
],
"fields": [
{
@@ -37,7 +39,7 @@
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Allocated Amount",
"options": "Currency",
"options": "currency",
"reqd": 1
},
{
@@ -112,7 +114,7 @@
"fieldtype": "Currency",
"hidden": 1,
"label": "Unreconciled Amount",
"options": "Currency",
"options": "currency",
"read_only": 1
},
{
@@ -120,7 +122,7 @@
"fieldtype": "Currency",
"hidden": 1,
"label": "Amount",
"options": "Currency",
"options": "currency",
"read_only": 1
},
{
@@ -129,11 +131,24 @@
"hidden": 1,
"label": "Reference Row",
"read_only": 1
},
{
"fieldname": "currency",
"fieldtype": "Link",
"hidden": 1,
"label": "Currency",
"options": "Currency"
},
{
"fieldname": "exchange_rate",
"fieldtype": "Float",
"label": "Exchange Rate",
"read_only": 1
}
],
"istable": 1,
"links": [],
"modified": "2021-10-06 11:48:59.616562",
"modified": "2022-12-24 21:01:14.882747",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Reconciliation Allocation",
@@ -141,5 +156,6 @@
"permissions": [],
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -11,7 +11,8 @@
"col_break1",
"amount",
"outstanding_amount",
"currency"
"currency",
"exchange_rate"
],
"fields": [
{
@@ -62,11 +63,17 @@
"hidden": 1,
"label": "Currency",
"options": "Currency"
},
{
"fieldname": "exchange_rate",
"fieldtype": "Float",
"hidden": 1,
"label": "Exchange Rate"
}
],
"istable": 1,
"links": [],
"modified": "2021-08-24 22:42:40.923179",
"modified": "2022-11-08 18:18:02.502149",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Reconciliation Invoice",
@@ -75,5 +82,6 @@
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -15,7 +15,8 @@
"difference_amount",
"sec_break1",
"remark",
"currency"
"currency",
"exchange_rate"
],
"fields": [
{
@@ -91,11 +92,17 @@
"label": "Difference Amount",
"options": "currency",
"read_only": 1
},
{
"fieldname": "exchange_rate",
"fieldtype": "Float",
"hidden": 1,
"label": "Exchange Rate"
}
],
"istable": 1,
"links": [],
"modified": "2021-08-30 10:51:48.140062",
"modified": "2022-11-08 18:18:36.268760",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Reconciliation Payment",
@@ -103,5 +110,6 @@
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC"
"sort_order": "DESC",
"states": []
}

View File

@@ -42,7 +42,7 @@ frappe.ui.form.on("Payment Request", "refresh", function(frm) {
});
}
if(!frm.doc.payment_gateway_account && frm.doc.status == "Initiated") {
if((!frm.doc.payment_gateway_account || frm.doc.payment_request_type == "Outward") && frm.doc.status == "Initiated") {
frm.add_custom_button(__('Create Payment Entry'), function(){
frappe.call({
method: "erpnext.accounts.doctype.payment_request.payment_request.make_payment_entry",

View File

@@ -32,6 +32,10 @@
"iban",
"branch_code",
"swift_number",
"accounting_dimensions_section",
"cost_center",
"dimension_col_break",
"project",
"recipient_and_message",
"print_format",
"email_to",
@@ -362,13 +366,35 @@
"label": "Payment Channel",
"options": "\nEmail\nPhone",
"read_only": 1
},
{
"collapsible": 1,
"fieldname": "accounting_dimensions_section",
"fieldtype": "Section Break",
"label": "Accounting Dimensions"
},
{
"fieldname": "cost_center",
"fieldtype": "Link",
"label": "Cost Center",
"options": "Cost Center"
},
{
"fieldname": "dimension_col_break",
"fieldtype": "Column Break"
},
{
"fieldname": "project",
"fieldtype": "Link",
"label": "Project",
"options": "Project"
}
],
"in_create": 1,
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2022-09-30 16:19:43.680025",
"modified": "2022-12-21 16:56:40.115737",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Request",

View File

@@ -9,8 +9,10 @@ from frappe import _
from frappe.model.document import Document
from frappe.utils import flt, get_url, nowdate
from frappe.utils.background_jobs import enqueue
from payments.utils import get_payment_gateway_controller
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
get_accounting_dimensions,
)
from erpnext.accounts.doctype.payment_entry.payment_entry import (
get_company_defaults,
get_payment_entry,
@@ -19,6 +21,14 @@ from erpnext.accounts.doctype.subscription_plan.subscription_plan import get_pla
from erpnext.accounts.party import get_party_account, get_party_bank_account
from erpnext.accounts.utils import get_account_currency
from erpnext.erpnext_integrations.stripe_integration import create_stripe_subscription
from erpnext.utilities import payment_app_import_guard
def _get_payment_gateway_controller(*args, **kwargs):
with payment_app_import_guard():
from payments.utils import get_payment_gateway_controller
return get_payment_gateway_controller(*args, **kwargs)
class PaymentRequest(Document):
@@ -35,21 +45,20 @@ class PaymentRequest(Document):
frappe.throw(_("To create a Payment Request reference document is required"))
def validate_payment_request_amount(self):
existing_payment_request_amount = get_existing_payment_request_amount(
self.reference_doctype, self.reference_name
existing_payment_request_amount = flt(
get_existing_payment_request_amount(self.reference_doctype, self.reference_name)
)
if existing_payment_request_amount:
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
if hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") != "Shopping Cart":
ref_amount = get_amount(ref_doc, self.payment_account)
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
if not hasattr(ref_doc, "order_type") or getattr(ref_doc, "order_type") != "Shopping Cart":
ref_amount = get_amount(ref_doc, self.payment_account)
if existing_payment_request_amount + flt(self.grand_total) > ref_amount:
frappe.throw(
_("Total Payment Request amount cannot be greater than {0} amount").format(
self.reference_doctype
)
if existing_payment_request_amount + flt(self.grand_total) > ref_amount:
frappe.throw(
_("Total Payment Request amount cannot be greater than {0} amount").format(
self.reference_doctype
)
)
def validate_currency(self):
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
@@ -107,7 +116,7 @@ class PaymentRequest(Document):
self.request_phone_payment()
def request_phone_payment(self):
controller = get_payment_gateway_controller(self.payment_gateway)
controller = _get_payment_gateway_controller(self.payment_gateway)
request_amount = self.get_request_amount()
payment_record = dict(
@@ -156,7 +165,7 @@ class PaymentRequest(Document):
def payment_gateway_validation(self):
try:
controller = get_payment_gateway_controller(self.payment_gateway)
controller = _get_payment_gateway_controller(self.payment_gateway)
if hasattr(controller, "on_payment_request_submission"):
return controller.on_payment_request_submission(self)
else:
@@ -189,7 +198,7 @@ class PaymentRequest(Document):
)
data.update({"company": frappe.defaults.get_defaults().company})
controller = get_payment_gateway_controller(self.payment_gateway)
controller = _get_payment_gateway_controller(self.payment_gateway)
controller.validate_transaction_currency(self.currency)
if hasattr(controller, "validate_minimum_transaction_amount"):
@@ -254,6 +263,7 @@ class PaymentRequest(Document):
payment_entry.update(
{
"mode_of_payment": self.mode_of_payment,
"reference_no": self.name,
"reference_date": nowdate(),
"remarks": "Payment Entry against {0} {1} via Payment Request {2}".format(
@@ -262,6 +272,17 @@ class PaymentRequest(Document):
}
)
# Update dimensions
payment_entry.update(
{
"cost_center": self.get("cost_center"),
"project": self.get("project"),
}
)
for dimension in get_accounting_dimensions():
payment_entry.update({dimension: self.get(dimension)})
if payment_entry.difference_amount:
company_details = get_company_defaults(ref_doc.company)
@@ -403,25 +424,22 @@ def make_payment_request(**args):
else ""
)
existing_payment_request = None
if args.order_type == "Shopping Cart":
existing_payment_request = frappe.db.get_value(
"Payment Request",
{"reference_doctype": args.dt, "reference_name": args.dn, "docstatus": ("!=", 2)},
)
draft_payment_request = frappe.db.get_value(
"Payment Request",
{"reference_doctype": args.dt, "reference_name": args.dn, "docstatus": 0},
)
if existing_payment_request:
existing_payment_request_amount = get_existing_payment_request_amount(args.dt, args.dn)
if existing_payment_request_amount:
grand_total -= existing_payment_request_amount
if draft_payment_request:
frappe.db.set_value(
"Payment Request", existing_payment_request, "grand_total", grand_total, update_modified=False
"Payment Request", draft_payment_request, "grand_total", grand_total, update_modified=False
)
pr = frappe.get_doc("Payment Request", existing_payment_request)
pr = frappe.get_doc("Payment Request", draft_payment_request)
else:
if args.order_type != "Shopping Cart":
existing_payment_request_amount = get_existing_payment_request_amount(args.dt, args.dn)
if existing_payment_request_amount:
grand_total -= existing_payment_request_amount
pr = frappe.new_doc("Payment Request")
pr.update(
{
@@ -444,6 +462,17 @@ def make_payment_request(**args):
}
)
# Update dimensions
pr.update(
{
"cost_center": ref_doc.get("cost_center"),
"project": ref_doc.get("project"),
}
)
for dimension in get_accounting_dimensions():
pr.update({dimension: ref_doc.get(dimension)})
if args.order_type == "Shopping Cart" or args.mute_email:
pr.flags.mute_email = True
@@ -466,26 +495,28 @@ def get_amount(ref_doc, payment_account=None):
"""get amount based on doctype"""
dt = ref_doc.doctype
if dt in ["Sales Order", "Purchase Order"]:
grand_total = flt(ref_doc.grand_total) - flt(ref_doc.advance_paid)
grand_total = flt(ref_doc.rounded_total) or flt(ref_doc.grand_total)
elif dt in ["Sales Invoice", "Purchase Invoice"]:
if ref_doc.party_account_currency == ref_doc.currency:
grand_total = flt(ref_doc.outstanding_amount)
else:
grand_total = flt(ref_doc.outstanding_amount) / ref_doc.conversion_rate
if not ref_doc.get("is_pos"):
if ref_doc.party_account_currency == ref_doc.currency:
grand_total = flt(ref_doc.outstanding_amount)
else:
grand_total = flt(ref_doc.outstanding_amount) / ref_doc.conversion_rate
elif dt == "Sales Invoice":
for pay in ref_doc.payments:
if pay.type == "Phone" and pay.account == payment_account:
grand_total = pay.amount
break
elif dt == "POS Invoice":
for pay in ref_doc.payments:
if pay.type == "Phone" and pay.account == payment_account:
grand_total = pay.amount
break
elif dt == "Fees":
grand_total = ref_doc.outstanding_amount
if grand_total > 0:
return grand_total
else:
frappe.throw(_("Payment Entry is already created"))

View File

@@ -6,6 +6,7 @@ import unittest
import frappe
from erpnext.accounts.doctype.payment_request.payment_request import make_payment_request
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
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
from erpnext.setup.utils import get_exchange_rate
@@ -45,7 +46,10 @@ class TestPaymentRequest(unittest.TestCase):
frappe.get_doc(method).insert(ignore_permissions=True)
def test_payment_request_linkings(self):
so_inr = make_sales_order(currency="INR")
so_inr = make_sales_order(currency="INR", do_not_save=True)
so_inr.disable_rounded_total = 1
so_inr.save()
pr = make_payment_request(
dt="Sales Order",
dn=so_inr.name,
@@ -71,6 +75,29 @@ class TestPaymentRequest(unittest.TestCase):
self.assertEqual(pr.reference_name, si_usd.name)
self.assertEqual(pr.currency, "USD")
def test_payment_entry_against_purchase_invoice(self):
si_usd = make_purchase_invoice(
customer="_Test Supplier USD",
debit_to="_Test Payable USD - _TC",
currency="USD",
conversion_rate=50,
)
pr = make_payment_request(
dt="Purchase Invoice",
dn=si_usd.name,
recipient_id="user@example.com",
mute_email=1,
payment_gateway_account="_Test Gateway - USD",
submit_doc=1,
return_doc=1,
)
pe = pr.create_payment_entry()
pr.load_from_db()
self.assertEqual(pr.status, "Paid")
def test_payment_entry(self):
frappe.db.set_value(
"Company", "_Test Company", "exchange_gain_loss_account", "_Test Exchange Gain/Loss - _TC"

View File

@@ -4,12 +4,13 @@
import frappe
from frappe import _
from frappe.utils import flt
from frappe.query_builder.functions import Sum
from frappe.utils import add_days, flt
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
get_accounting_dimensions,
)
from erpnext.accounts.utils import get_account_currency
from erpnext.accounts.utils import get_account_currency, get_fiscal_year, validate_fiscal_year
from erpnext.controllers.accounts_controller import AccountsController
@@ -20,9 +21,17 @@ class PeriodClosingVoucher(AccountsController):
def on_submit(self):
self.db_set("gle_processing_status", "In Progress")
self.make_gl_entries()
get_opening_entries = False
if not frappe.db.exists(
"Period Closing Voucher", {"company": self.company, "docstatus": 1, "name": ("!=", self.name)}
):
get_opening_entries = True
self.make_gl_entries(get_opening_entries=get_opening_entries)
def on_cancel(self):
self.validate_future_closing_vouchers()
self.db_set("gle_processing_status", "In Progress")
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry")
gle_count = frappe.db.count(
@@ -35,6 +44,7 @@ class PeriodClosingVoucher(AccountsController):
voucher_type="Period Closing Voucher",
voucher_no=self.name,
queue="long",
enqueue_after_commit=True,
)
frappe.msgprint(
_("The GL Entries will be cancelled in the background, it can take a few minutes."), alert=True
@@ -42,6 +52,25 @@ class PeriodClosingVoucher(AccountsController):
else:
make_reverse_gl_entries(voucher_type="Period Closing Voucher", voucher_no=self.name)
self.delete_closing_entries()
def validate_future_closing_vouchers(self):
if frappe.db.exists(
"Period Closing Voucher",
{"posting_date": (">", self.posting_date), "docstatus": 1, "company": self.company},
):
frappe.throw(
_(
"You can not cancel this Period Closing Voucher, please cancel the future Period Closing Vouchers first"
)
)
def delete_closing_entries(self):
closing_balance = frappe.qb.DocType("Account Closing Balance")
frappe.qb.from_(closing_balance).delete().where(
closing_balance.period_closing_voucher == self.name
).run()
def validate_account_head(self):
closing_account_type = frappe.get_cached_value("Account", self.closing_account_head, "root_type")
@@ -56,8 +85,6 @@ class PeriodClosingVoucher(AccountsController):
frappe.throw(_("Currency of the Closing Account must be {0}").format(company_currency))
def validate_posting_date(self):
from erpnext.accounts.utils import get_fiscal_year, validate_fiscal_year
validate_fiscal_year(
self.posting_date, self.fiscal_year, self.company, label=_("Posting Date"), doc=self
)
@@ -66,6 +93,8 @@ class PeriodClosingVoucher(AccountsController):
self.posting_date, self.fiscal_year, company=self.company
)[1]
self.check_if_previous_year_closed()
pce = frappe.db.sql(
"""select name from `tabPeriod Closing Voucher`
where posting_date > %s and fiscal_year = %s and docstatus = 1 and company = %s""",
@@ -78,28 +107,64 @@ class PeriodClosingVoucher(AccountsController):
)
)
def make_gl_entries(self):
def check_if_previous_year_closed(self):
last_year_closing = add_days(self.year_start_date, -1)
previous_fiscal_year = get_fiscal_year(last_year_closing, company=self.company, boolean=True)
if previous_fiscal_year and not frappe.db.exists(
"GL Entry", {"posting_date": ("<=", last_year_closing), "company": self.company}
):
return
if previous_fiscal_year and not frappe.db.exists(
"Period Closing Voucher",
{"posting_date": ("<=", last_year_closing), "docstatus": 1, "company": self.company},
):
frappe.throw(_("Previous Year is not closed, please close it first"))
def make_gl_entries(self, get_opening_entries=False):
gl_entries = self.get_gl_entries()
closing_entries = self.get_grouped_gl_entries(get_opening_entries=get_opening_entries)
if gl_entries:
if len(gl_entries) > 5000:
frappe.enqueue(process_gl_entries, gl_entries=gl_entries, queue="long")
frappe.enqueue(
process_gl_entries,
gl_entries=gl_entries,
closing_entries=closing_entries,
voucher_name=self.name,
queue="long",
)
frappe.msgprint(
_("The GL Entries will be processed in the background, it can take a few minutes."),
alert=True,
)
else:
process_gl_entries(gl_entries)
process_gl_entries(gl_entries, closing_entries, voucher_name=self.name)
def get_grouped_gl_entries(self, get_opening_entries=False):
closing_entries = []
for acc in self.get_balances_based_on_dimensions(
group_by_account=True, for_aggregation=True, get_opening_entries=get_opening_entries
):
closing_entries.append(self.get_closing_entries(acc))
return closing_entries
def get_gl_entries(self):
gl_entries = []
# pl account
for acc in self.get_pl_balances_based_on_dimensions(group_by_account=True):
for acc in self.get_balances_based_on_dimensions(
group_by_account=True, report_type="Profit and Loss"
):
if flt(acc.bal_in_company_currency):
gl_entries.append(self.get_gle_for_pl_account(acc))
# closing liability account
for acc in self.get_pl_balances_based_on_dimensions(group_by_account=False):
for acc in self.get_balances_based_on_dimensions(
group_by_account=False, report_type="Profit and Loss"
):
if flt(acc.bal_in_company_currency):
gl_entries.append(self.get_gle_for_closing_account(acc))
@@ -108,6 +173,8 @@ class PeriodClosingVoucher(AccountsController):
def get_gle_for_pl_account(self, acc):
gl_entry = self.get_gl_dict(
{
"company": self.company,
"closing_date": self.posting_date,
"account": acc.account,
"cost_center": acc.cost_center,
"finance_book": acc.finance_book,
@@ -120,6 +187,7 @@ class PeriodClosingVoucher(AccountsController):
if flt(acc.bal_in_account_currency) > 0
else 0,
"credit": abs(flt(acc.bal_in_company_currency)) if flt(acc.bal_in_company_currency) > 0 else 0,
"is_period_closing_voucher_entry": 1,
},
item=acc,
)
@@ -129,6 +197,8 @@ class PeriodClosingVoucher(AccountsController):
def get_gle_for_closing_account(self, acc):
gl_entry = self.get_gl_dict(
{
"company": self.company,
"closing_date": self.posting_date,
"account": self.closing_account_head,
"cost_center": acc.cost_center,
"finance_book": acc.finance_book,
@@ -141,12 +211,36 @@ class PeriodClosingVoucher(AccountsController):
if flt(acc.bal_in_account_currency) < 0
else 0,
"credit": abs(flt(acc.bal_in_company_currency)) if flt(acc.bal_in_company_currency) < 0 else 0,
"is_period_closing_voucher_entry": 1,
},
item=acc,
)
self.update_default_dimensions(gl_entry, acc)
return gl_entry
def get_closing_entries(self, acc):
closing_entry = self.get_gl_dict(
{
"company": self.company,
"closing_date": self.posting_date,
"period_closing_voucher": self.name,
"account": acc.account,
"cost_center": acc.cost_center,
"finance_book": acc.finance_book,
"account_currency": acc.account_currency,
"debit_in_account_currency": flt(acc.debit_in_account_currency),
"debit": flt(acc.debit),
"credit_in_account_currency": flt(acc.credit_in_account_currency),
"credit": flt(acc.credit),
},
item=acc,
)
for dimension in self.accounting_dimensions:
closing_entry.update({dimension: acc.get(dimension)})
return closing_entry
def update_default_dimensions(self, gl_entry, acc):
if not self.accounting_dimensions:
self.accounting_dimensions = get_accounting_dimensions()
@@ -154,47 +248,88 @@ class PeriodClosingVoucher(AccountsController):
for dimension in self.accounting_dimensions:
gl_entry.update({dimension: acc.get(dimension)})
def get_pl_balances_based_on_dimensions(self, group_by_account=False):
def get_balances_based_on_dimensions(
self, group_by_account=False, report_type=None, for_aggregation=False, get_opening_entries=False
):
"""Get balance for dimension-wise pl accounts"""
dimension_fields = ["t1.cost_center", "t1.finance_book"]
qb_dimension_fields = ["cost_center", "finance_book", "project"]
self.accounting_dimensions = get_accounting_dimensions()
for dimension in self.accounting_dimensions:
dimension_fields.append("t1.{0}".format(dimension))
qb_dimension_fields.append(dimension)
if group_by_account:
dimension_fields.append("t1.account")
qb_dimension_fields.append("account")
return frappe.db.sql(
"""
select
t2.account_currency,
{dimension_fields},
sum(t1.debit_in_account_currency) - sum(t1.credit_in_account_currency) as bal_in_account_currency,
sum(t1.debit) - sum(t1.credit) as bal_in_company_currency
from `tabGL Entry` t1, `tabAccount` t2
where
t1.is_cancelled = 0
and t1.account = t2.name
and t2.report_type = 'Profit and Loss'
and t2.docstatus < 2
and t2.company = %s
and t1.posting_date between %s and %s
group by {dimension_fields}
""".format(
dimension_fields=", ".join(dimension_fields)
),
(self.company, self.get("year_start_date"), self.posting_date),
as_dict=1,
account_filters = {
"company": self.company,
"is_group": 0,
}
if report_type:
account_filters.update({"report_type": report_type})
accounts = frappe.get_all("Account", filters=account_filters, pluck="name")
gl_entry = frappe.qb.DocType("GL Entry")
query = frappe.qb.from_(gl_entry).select(gl_entry.account, gl_entry.account_currency)
if not for_aggregation:
query = query.select(
(Sum(gl_entry.debit_in_account_currency) - Sum(gl_entry.credit_in_account_currency)).as_(
"bal_in_account_currency"
),
(Sum(gl_entry.debit) - Sum(gl_entry.credit)).as_("bal_in_company_currency"),
)
else:
query = query.select(
(Sum(gl_entry.debit_in_account_currency)).as_("debit_in_account_currency"),
(Sum(gl_entry.credit_in_account_currency)).as_("credit_in_account_currency"),
(Sum(gl_entry.debit)).as_("debit"),
(Sum(gl_entry.credit)).as_("credit"),
)
for dimension in qb_dimension_fields:
query = query.select(gl_entry[dimension])
query = query.where(
(gl_entry.company == self.company)
& (gl_entry.is_cancelled == 0)
& (gl_entry.account.isin(accounts))
)
if get_opening_entries:
query = query.where(
gl_entry.posting_date.between(self.get("year_start_date"), self.posting_date)
| gl_entry.is_opening
== "Yes"
)
else:
query = query.where(
gl_entry.posting_date.between(self.get("year_start_date"), self.posting_date)
& gl_entry.is_opening
== "No"
)
def process_gl_entries(gl_entries):
if for_aggregation:
query = query.where(gl_entry.voucher_type != "Period Closing Voucher")
for dimension in qb_dimension_fields:
query = query.groupby(gl_entry[dimension])
return query.run(as_dict=1)
def process_gl_entries(gl_entries, closing_entries, voucher_name=None):
from erpnext.accounts.doctype.account_closing_balance.account_closing_balance import (
make_closing_entries,
)
from erpnext.accounts.general_ledger import make_gl_entries
try:
make_gl_entries(gl_entries, merge_entries=False)
make_closing_entries(gl_entries + closing_entries, voucher_name=voucher_name)
frappe.db.set_value(
"Period Closing Voucher", gl_entries[0].get("voucher_no"), "gle_processing_status", "Completed"
)

View File

@@ -16,16 +16,17 @@ from erpnext.accounts.utils import get_fiscal_year, now
class TestPeriodClosingVoucher(unittest.TestCase):
def test_closing_entry(self):
frappe.db.sql("delete from `tabGL Entry` where company='Test PCV Company'")
frappe.db.sql("delete from `tabPeriod Closing Voucher` where company='Test PCV Company'")
company = create_company()
cost_center = create_cost_center("Test Cost Center 1")
jv1 = make_journal_entry(
posting_date="2021-03-15",
amount=400,
account1="Cash - TPC",
account2="Sales - TPC",
cost_center=cost_center,
posting_date=now(),
save=False,
)
jv1.company = company
@@ -33,18 +34,18 @@ class TestPeriodClosingVoucher(unittest.TestCase):
jv1.submit()
jv2 = make_journal_entry(
posting_date="2021-03-15",
amount=600,
account1="Cost of Goods Sold - TPC",
account2="Cash - TPC",
cost_center=cost_center,
posting_date=now(),
save=False,
)
jv2.company = company
jv2.save()
jv2.submit()
pcv = self.make_period_closing_voucher()
pcv = self.make_period_closing_voucher(posting_date="2021-03-31")
surplus_account = pcv.closing_account_head
expected_gle = (
@@ -65,6 +66,7 @@ class TestPeriodClosingVoucher(unittest.TestCase):
def test_cost_center_wise_posting(self):
frappe.db.sql("delete from `tabGL Entry` where company='Test PCV Company'")
frappe.db.sql("delete from `tabPeriod Closing Voucher` where company='Test PCV Company'")
company = create_company()
surplus_account = create_account()
@@ -81,6 +83,7 @@ class TestPeriodClosingVoucher(unittest.TestCase):
debit_to="Debtors - TPC",
currency="USD",
customer="_Test Customer USD",
posting_date="2021-03-15",
)
create_sales_invoice(
company=company,
@@ -91,9 +94,10 @@ class TestPeriodClosingVoucher(unittest.TestCase):
debit_to="Debtors - TPC",
currency="USD",
customer="_Test Customer USD",
posting_date="2021-03-15",
)
pcv = self.make_period_closing_voucher(submit=False)
pcv = self.make_period_closing_voucher(posting_date="2021-03-31", submit=False)
pcv.save()
pcv.submit()
surplus_account = pcv.closing_account_head
@@ -128,12 +132,13 @@ class TestPeriodClosingVoucher(unittest.TestCase):
def test_period_closing_with_finance_book_entries(self):
frappe.db.sql("delete from `tabGL Entry` where company='Test PCV Company'")
frappe.db.sql("delete from `tabPeriod Closing Voucher` where company='Test PCV Company'")
company = create_company()
surplus_account = create_account()
cost_center = create_cost_center("Test Cost Center 1")
si = create_sales_invoice(
create_sales_invoice(
company=company,
income_account="Sales - TPC",
expense_account="Cost of Goods Sold - TPC",
@@ -142,6 +147,7 @@ class TestPeriodClosingVoucher(unittest.TestCase):
debit_to="Debtors - TPC",
currency="USD",
customer="_Test Customer USD",
posting_date="2021-03-15",
)
jv = make_journal_entry(
@@ -149,14 +155,14 @@ class TestPeriodClosingVoucher(unittest.TestCase):
account2="Sales - TPC",
amount=400,
cost_center=cost_center,
posting_date=now(),
posting_date="2021-03-15",
)
jv.company = company
jv.finance_book = create_finance_book().name
jv.save()
jv.submit()
pcv = self.make_period_closing_voucher()
pcv = self.make_period_closing_voucher(posting_date="2021-03-31")
surplus_account = pcv.closing_account_head
expected_gle = (
@@ -177,14 +183,148 @@ class TestPeriodClosingVoucher(unittest.TestCase):
self.assertSequenceEqual(pcv_gle, expected_gle)
def make_period_closing_voucher(self, submit=True):
def test_gl_entries_restrictions(self):
frappe.db.sql("delete from `tabGL Entry` where company='Test PCV Company'")
frappe.db.sql("delete from `tabPeriod Closing Voucher` where company='Test PCV Company'")
company = create_company()
cost_center = create_cost_center("Test Cost Center 1")
self.make_period_closing_voucher(posting_date="2021-03-31")
jv1 = make_journal_entry(
posting_date="2021-03-15",
amount=400,
account1="Cash - TPC",
account2="Sales - TPC",
cost_center=cost_center,
save=False,
)
jv1.company = company
jv1.save()
self.assertRaises(frappe.ValidationError, jv1.submit)
def test_closing_balance_with_dimensions_and_test_reposting_entry(self):
frappe.db.sql("delete from `tabGL Entry` where company='Test PCV Company'")
frappe.db.sql("delete from `tabPeriod Closing Voucher` where company='Test PCV Company'")
frappe.db.sql("delete from `tabAccount Closing Balance` where company='Test PCV Company'")
company = create_company()
cost_center1 = create_cost_center("Test Cost Center 1")
cost_center2 = create_cost_center("Test Cost Center 2")
jv1 = make_journal_entry(
posting_date="2021-03-15",
amount=400,
account1="Cash - TPC",
account2="Sales - TPC",
cost_center=cost_center1,
save=False,
)
jv1.company = company
jv1.save()
jv1.submit()
jv2 = make_journal_entry(
posting_date="2021-03-15",
amount=200,
account1="Cash - TPC",
account2="Sales - TPC",
cost_center=cost_center2,
save=False,
)
jv2.company = company
jv2.save()
jv2.submit()
pcv1 = self.make_period_closing_voucher(posting_date="2021-03-31")
closing_balance = frappe.db.get_value(
"Account Closing Balance",
{
"account": "Sales - TPC",
"cost_center": cost_center1,
"period_closing_voucher": pcv1.name,
"is_period_closing_voucher_entry": 0,
},
["credit", "credit_in_account_currency"],
as_dict=1,
)
self.assertEqual(closing_balance.credit, 400)
self.assertEqual(closing_balance.credit_in_account_currency, 400)
jv3 = make_journal_entry(
posting_date="2022-03-15",
amount=300,
account1="Cash - TPC",
account2="Sales - TPC",
cost_center=cost_center2,
save=False,
)
jv3.company = company
jv3.save()
jv3.submit()
pcv2 = self.make_period_closing_voucher(posting_date="2022-03-31")
cc1_closing_balance = frappe.db.get_value(
"Account Closing Balance",
{
"account": "Sales - TPC",
"cost_center": cost_center1,
"period_closing_voucher": pcv2.name,
"is_period_closing_voucher_entry": 0,
},
["credit", "credit_in_account_currency"],
as_dict=1,
)
cc2_closing_balance = frappe.db.get_value(
"Account Closing Balance",
{
"account": "Sales - TPC",
"cost_center": cost_center2,
"period_closing_voucher": pcv2.name,
"is_period_closing_voucher_entry": 0,
},
["credit", "credit_in_account_currency"],
as_dict=1,
)
self.assertEqual(cc1_closing_balance.credit, 400)
self.assertEqual(cc1_closing_balance.credit_in_account_currency, 400)
self.assertEqual(cc2_closing_balance.credit, 500)
self.assertEqual(cc2_closing_balance.credit_in_account_currency, 500)
warehouse = frappe.db.get_value("Warehouse", {"company": company}, "name")
repost_doc = frappe.get_doc(
{
"doctype": "Repost Item Valuation",
"company": company,
"posting_date": "2020-03-15",
"based_on": "Item and Warehouse",
"item_code": "Test Item 1",
"warehouse": warehouse,
}
)
self.assertRaises(frappe.ValidationError, repost_doc.save)
repost_doc.posting_date = today()
repost_doc.save()
def make_period_closing_voucher(self, posting_date=None, submit=True):
surplus_account = create_account()
cost_center = create_cost_center("Test Cost Center 1")
pcv = frappe.get_doc(
{
"doctype": "Period Closing Voucher",
"transaction_date": today(),
"posting_date": today(),
"transaction_date": posting_date or today(),
"posting_date": posting_date or today(),
"company": "Test PCV Company",
"fiscal_year": get_fiscal_year(today(), company="Test PCV Company")[0],
"cost_center": cost_center,

View File

@@ -21,8 +21,24 @@ class POSClosingEntry(StatusUpdater):
if frappe.db.get_value("POS Opening Entry", self.pos_opening_entry, "status") != "Open":
frappe.throw(_("Selected POS Opening Entry should be open."), title=_("Invalid Opening Entry"))
self.validate_duplicate_pos_invoices()
self.validate_pos_invoices()
def validate_duplicate_pos_invoices(self):
pos_occurences = {}
for idx, inv in enumerate(self.pos_transactions, 1):
pos_occurences.setdefault(inv.pos_invoice, []).append(idx)
error_list = []
for key, value in pos_occurences.items():
if len(value) > 1:
error_list.append(
_("{} is added multiple times on rows: {}".format(frappe.bold(key), frappe.bold(value)))
)
if error_list:
frappe.throw(error_list, title=_("Duplicate POS Invoices found"), as_list=True)
def validate_pos_invoices(self):
invalid_rows = []
for d in self.pos_transactions:

View File

@@ -112,7 +112,8 @@ erpnext.selling.POSInvoiceController = class POSInvoiceController extends erpnex
party_type: "Customer",
account: this.frm.doc.debit_to,
price_list: this.frm.doc.selling_price_list,
pos_profile: pos_profile
pos_profile: pos_profile,
company_address: this.frm.doc.company_address
}, () => {
this.apply_pricing_rule();
});

View File

@@ -442,6 +442,7 @@
"fieldtype": "Data",
"hidden": 1,
"label": "Mobile No",
"options": "Phone",
"read_only": 1
},
{
@@ -1554,11 +1555,10 @@
"icon": "fa fa-file-text",
"is_submittable": 1,
"links": [],
"modified": "2022-09-30 03:49:50.455199",
"modified": "2023-06-03 16:23:41.083409",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Invoice",
"name_case": "Title Case",
"naming_rule": "By \"Naming Series\" field",
"owner": "Administrator",
"permissions": [

View File

@@ -3,7 +3,8 @@
import frappe
from frappe import _
from frappe import _, bold
from frappe.query_builder.functions import IfNull, Sum
from frappe.utils import cint, flt, get_link_to_form, getdate, nowdate
from erpnext.accounts.doctype.loyalty_program.loyalty_program import validate_loyalty_points
@@ -15,12 +16,7 @@ from erpnext.accounts.doctype.sales_invoice.sales_invoice import (
update_multi_mode_option,
)
from erpnext.accounts.party import get_due_date, get_party_account
from erpnext.stock.doctype.batch.batch import get_batch_qty, get_pos_reserved_batch_qty
from erpnext.stock.doctype.serial_no.serial_no import (
get_delivered_serial_nos,
get_pos_reserved_serial_nos,
get_serial_nos,
)
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
class POSInvoice(SalesInvoice):
@@ -70,6 +66,7 @@ class POSInvoice(SalesInvoice):
self.apply_loyalty_points()
self.check_phone_payments()
self.set_status(update=True)
self.submit_serial_batch_bundle()
if self.coupon_code:
from erpnext.accounts.doctype.pricing_rule.utils import update_coupon_code_count
@@ -111,6 +108,29 @@ class POSInvoice(SalesInvoice):
update_coupon_code_count(self.coupon_code, "cancelled")
self.delink_serial_and_batch_bundle()
def delink_serial_and_batch_bundle(self):
for row in self.items:
if row.serial_and_batch_bundle:
if not self.consolidated_invoice:
frappe.db.set_value(
"Serial and Batch Bundle",
row.serial_and_batch_bundle,
{"is_cancelled": 1, "voucher_no": ""},
)
row.db_set("serial_and_batch_bundle", None)
def submit_serial_batch_bundle(self):
for item in self.items:
if item.serial_and_batch_bundle:
doc = frappe.get_doc("Serial and Batch Bundle", item.serial_and_batch_bundle)
if doc.docstatus == 0:
doc.flags.ignore_voucher_validation = True
doc.submit()
def check_phone_payments(self):
for pay in self.payments:
if pay.type == "Phone" and pay.amount >= 0:
@@ -128,88 +148,6 @@ class POSInvoice(SalesInvoice):
if paid_amt and pay.amount != paid_amt:
return frappe.throw(_("Payment related to {0} is not completed").format(pay.mode_of_payment))
def validate_pos_reserved_serial_nos(self, item):
serial_nos = get_serial_nos(item.serial_no)
filters = {"item_code": item.item_code, "warehouse": item.warehouse}
if item.batch_no:
filters["batch_no"] = item.batch_no
reserved_serial_nos = get_pos_reserved_serial_nos(filters)
invalid_serial_nos = [s for s in serial_nos if s in reserved_serial_nos]
bold_invalid_serial_nos = frappe.bold(", ".join(invalid_serial_nos))
if len(invalid_serial_nos) == 1:
frappe.throw(
_(
"Row #{}: Serial No. {} has already been transacted into another POS Invoice. Please select valid serial no."
).format(item.idx, bold_invalid_serial_nos),
title=_("Item Unavailable"),
)
elif invalid_serial_nos:
frappe.throw(
_(
"Row #{}: Serial Nos. {} have already been transacted into another POS Invoice. Please select valid serial no."
).format(item.idx, bold_invalid_serial_nos),
title=_("Item Unavailable"),
)
def validate_pos_reserved_batch_qty(self, item):
filters = {"item_code": item.item_code, "warehouse": item.warehouse, "batch_no": item.batch_no}
available_batch_qty = get_batch_qty(item.batch_no, item.warehouse, item.item_code)
reserved_batch_qty = get_pos_reserved_batch_qty(filters)
bold_item_name = frappe.bold(item.item_name)
bold_extra_batch_qty_needed = frappe.bold(
abs(available_batch_qty - reserved_batch_qty - item.qty)
)
bold_invalid_batch_no = frappe.bold(item.batch_no)
if (available_batch_qty - reserved_batch_qty) == 0:
frappe.throw(
_(
"Row #{}: Batch No. {} of item {} has no stock available. Please select valid batch no."
).format(item.idx, bold_invalid_batch_no, bold_item_name),
title=_("Item Unavailable"),
)
elif (available_batch_qty - reserved_batch_qty - item.qty) < 0:
frappe.throw(
_(
"Row #{}: Batch No. {} of item {} has less than required stock available, {} more required"
).format(
item.idx, bold_invalid_batch_no, bold_item_name, bold_extra_batch_qty_needed
),
title=_("Item Unavailable"),
)
def validate_delivered_serial_nos(self, item):
delivered_serial_nos = get_delivered_serial_nos(item.serial_no)
if delivered_serial_nos:
bold_delivered_serial_nos = frappe.bold(", ".join(delivered_serial_nos))
frappe.throw(
_(
"Row #{}: Serial No. {} has already been transacted into another Sales Invoice. Please select valid serial no."
).format(item.idx, bold_delivered_serial_nos),
title=_("Item Unavailable"),
)
def validate_invalid_serial_nos(self, item):
serial_nos = get_serial_nos(item.serial_no)
error_msg = []
invalid_serials, msg = "", ""
for serial_no in serial_nos:
if not frappe.db.exists("Serial No", serial_no):
invalid_serials = invalid_serials + (", " if invalid_serials else "") + serial_no
msg = _("Row #{}: Following Serial numbers for item {} are <b>Invalid</b>: {}").format(
item.idx, frappe.bold(item.get("item_code")), frappe.bold(invalid_serials)
)
if invalid_serials:
error_msg.append(msg)
if error_msg:
frappe.throw(error_msg, title=_("Invalid Item"), as_list=True)
def validate_stock_availablility(self):
if self.is_return:
return
@@ -222,13 +160,7 @@ class POSInvoice(SalesInvoice):
from erpnext.stock.stock_ledger import is_negative_stock_allowed
for d in self.get("items"):
if d.serial_no:
self.validate_pos_reserved_serial_nos(d)
self.validate_delivered_serial_nos(d)
self.validate_invalid_serial_nos(d)
elif d.batch_no:
self.validate_pos_reserved_batch_qty(d)
else:
if not d.serial_and_batch_bundle:
if is_negative_stock_allowed(item_code=d.item_code):
return
@@ -246,7 +178,7 @@ class POSInvoice(SalesInvoice):
),
title=_("Item Unavailable"),
)
elif is_stock_item and flt(available_stock) < flt(d.qty):
elif is_stock_item and flt(available_stock) < flt(d.stock_qty):
frappe.throw(
_(
"Row #{}: Stock quantity not enough for Item Code: {} under warehouse {}. Available quantity {}."
@@ -257,36 +189,15 @@ class POSInvoice(SalesInvoice):
def validate_serialised_or_batched_item(self):
error_msg = []
for d in self.get("items"):
serialized = d.get("has_serial_no")
batched = d.get("has_batch_no")
no_serial_selected = not d.get("serial_no")
no_batch_selected = not d.get("batch_no")
error_msg = ""
if d.get("has_serial_no") and not d.serial_and_batch_bundle:
error_msg = f"Row #{d.idx}: Please select Serial No. for item {bold(d.item_code)}"
msg = ""
item_code = frappe.bold(d.item_code)
serial_nos = get_serial_nos(d.serial_no)
if serialized and batched and (no_batch_selected or no_serial_selected):
msg = _(
"Row #{}: Please select a serial no and batch against item: {} or remove it to complete transaction."
).format(d.idx, item_code)
elif serialized and no_serial_selected:
msg = _(
"Row #{}: No serial number selected against item: {}. Please select one or remove it to complete transaction."
).format(d.idx, item_code)
elif batched and no_batch_selected:
msg = _(
"Row #{}: No batch selected against item: {}. Please select a batch or remove it to complete transaction."
).format(d.idx, item_code)
elif serialized and not no_serial_selected and len(serial_nos) != d.qty:
msg = _("Row #{}: You must select {} serial numbers for item {}.").format(
d.idx, frappe.bold(cint(d.qty)), item_code
)
if msg:
error_msg.append(msg)
elif d.get("has_batch_no") and not d.serial_and_batch_bundle:
error_msg = f"Row #{d.idx}: Please select Batch No. for item {bold(d.item_code)}"
if error_msg:
frappe.throw(error_msg, title=_("Invalid Item"), as_list=True)
frappe.throw(error_msg, title=_("Serial / Batch Bundle Missing"), as_list=True)
def validate_return_items_qty(self):
if not self.get("is_return"):
@@ -674,18 +585,22 @@ def get_bin_qty(item_code, warehouse):
def get_pos_reserved_qty(item_code, warehouse):
reserved_qty = frappe.db.sql(
"""select sum(p_item.qty) as qty
from `tabPOS Invoice` p, `tabPOS Invoice Item` p_item
where p.name = p_item.parent
and ifnull(p.consolidated_invoice, '') = ''
and p_item.docstatus = 1
and p_item.item_code = %s
and p_item.warehouse = %s
""",
(item_code, warehouse),
as_dict=1,
)
p_inv = frappe.qb.DocType("POS Invoice")
p_item = frappe.qb.DocType("POS Invoice Item")
reserved_qty = (
frappe.qb.from_(p_inv)
.from_(p_item)
.select(Sum(p_item.qty).as_("qty"))
.where(
(p_inv.name == p_item.parent)
& (IfNull(p_inv.consolidated_invoice, "") == "")
& (p_inv.is_return == 0)
& (p_item.docstatus == 1)
& (p_item.item_code == item_code)
& (p_item.warehouse == warehouse)
)
).run(as_dict=True)
return reserved_qty[0].qty or 0 if reserved_qty else 0

View File

@@ -5,12 +5,18 @@ import copy
import unittest
import frappe
from frappe import _
from erpnext.accounts.doctype.pos_invoice.pos_invoice import make_sales_return
from erpnext.accounts.doctype.pos_profile.test_pos_profile import make_pos_profile
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
from erpnext.stock.doctype.item.test_item import make_item
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
from erpnext.stock.doctype.serial_and_batch_bundle.test_serial_and_batch_bundle import (
get_batch_from_bundle,
get_serial_nos_from_bundle,
make_serial_batch_bundle,
)
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
@@ -25,7 +31,7 @@ class TestPOSInvoice(unittest.TestCase):
frappe.set_user("Administrator")
if frappe.db.get_single_value("Selling Settings", "validate_selling_price"):
frappe.db.set_value("Selling Settings", None, "validate_selling_price", 0)
frappe.db.set_single_value("Selling Settings", "validate_selling_price", 0)
def test_timestamp_change(self):
w = create_pos_invoice(do_not_save=1)
@@ -249,7 +255,7 @@ class TestPOSInvoice(unittest.TestCase):
expense_account="Cost of Goods Sold - _TC",
)
serial_nos = get_serial_nos(se.get("items")[0].serial_no)
serial_nos = get_serial_nos_from_bundle(se.get("items")[0].serial_and_batch_bundle)
pos = create_pos_invoice(
company="_Test Company",
@@ -260,11 +266,11 @@ class TestPOSInvoice(unittest.TestCase):
expense_account="Cost of Goods Sold - _TC",
cost_center="Main - _TC",
item=se.get("items")[0].item_code,
serial_no=[serial_nos[0]],
rate=1000,
do_not_save=1,
)
pos.get("items")[0].serial_no = serial_nos[0]
pos.append(
"payments", {"mode_of_payment": "Cash", "account": "Cash - _TC", "amount": 1000, "default": 1}
)
@@ -276,7 +282,9 @@ class TestPOSInvoice(unittest.TestCase):
pos_return.insert()
pos_return.submit()
self.assertEqual(pos_return.get("items")[0].serial_no, serial_nos[0])
self.assertEqual(
get_serial_nos_from_bundle(pos_return.get("items")[0].serial_and_batch_bundle)[0], serial_nos[0]
)
def test_partial_pos_returns(self):
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
@@ -289,7 +297,7 @@ class TestPOSInvoice(unittest.TestCase):
expense_account="Cost of Goods Sold - _TC",
)
serial_nos = get_serial_nos(se.get("items")[0].serial_no)
serial_nos = get_serial_nos_from_bundle(se.get("items")[0].serial_and_batch_bundle)
pos = create_pos_invoice(
company="_Test Company",
@@ -300,12 +308,12 @@ class TestPOSInvoice(unittest.TestCase):
expense_account="Cost of Goods Sold - _TC",
cost_center="Main - _TC",
item=se.get("items")[0].item_code,
serial_no=serial_nos,
qty=2,
rate=1000,
do_not_save=1,
)
pos.get("items")[0].serial_no = serial_nos[0] + "\n" + serial_nos[1]
pos.append(
"payments", {"mode_of_payment": "Cash", "account": "Cash - _TC", "amount": 1000, "default": 1}
)
@@ -317,14 +325,27 @@ class TestPOSInvoice(unittest.TestCase):
# partial return 1
pos_return1.get("items")[0].qty = -1
pos_return1.get("items")[0].serial_no = serial_nos[0]
bundle_id = frappe.get_doc(
"Serial and Batch Bundle", pos_return1.get("items")[0].serial_and_batch_bundle
)
bundle_id.remove(bundle_id.entries[1])
bundle_id.save()
bundle_id.load_from_db()
serial_no = bundle_id.entries[0].serial_no
self.assertEqual(serial_no, serial_nos[0])
pos_return1.insert()
pos_return1.submit()
# partial return 2
pos_return2 = make_sales_return(pos.name)
self.assertEqual(pos_return2.get("items")[0].qty, -1)
self.assertEqual(pos_return2.get("items")[0].serial_no, serial_nos[1])
serial_no = get_serial_nos_from_bundle(pos_return2.get("items")[0].serial_and_batch_bundle)[0]
self.assertEqual(serial_no, serial_nos[1])
def test_pos_change_amount(self):
pos = create_pos_invoice(
@@ -368,7 +389,7 @@ class TestPOSInvoice(unittest.TestCase):
expense_account="Cost of Goods Sold - _TC",
)
serial_nos = get_serial_nos(se.get("items")[0].serial_no)
serial_nos = get_serial_nos_from_bundle(se.get("items")[0].serial_and_batch_bundle)
pos = create_pos_invoice(
company="_Test Company",
@@ -380,10 +401,10 @@ class TestPOSInvoice(unittest.TestCase):
cost_center="Main - _TC",
item=se.get("items")[0].item_code,
rate=1000,
serial_no=[serial_nos[0]],
do_not_save=1,
)
pos.get("items")[0].serial_no = serial_nos[0]
pos.append(
"payments", {"mode_of_payment": "Bank Draft", "account": "_Test Bank - _TC", "amount": 1000}
)
@@ -401,10 +422,10 @@ class TestPOSInvoice(unittest.TestCase):
cost_center="Main - _TC",
item=se.get("items")[0].item_code,
rate=1000,
serial_no=[serial_nos[0]],
do_not_save=1,
)
pos2.get("items")[0].serial_no = serial_nos[0]
pos2.append(
"payments", {"mode_of_payment": "Bank Draft", "account": "_Test Bank - _TC", "amount": 1000}
)
@@ -423,7 +444,7 @@ class TestPOSInvoice(unittest.TestCase):
expense_account="Cost of Goods Sold - _TC",
)
serial_nos = get_serial_nos(se.get("items")[0].serial_no)
serial_nos = get_serial_nos_from_bundle(se.get("items")[0].serial_and_batch_bundle)
si = create_sales_invoice(
company="_Test Company",
@@ -435,11 +456,11 @@ class TestPOSInvoice(unittest.TestCase):
cost_center="Main - _TC",
item=se.get("items")[0].item_code,
rate=1000,
update_stock=1,
serial_no=[serial_nos[0]],
do_not_save=1,
)
si.get("items")[0].serial_no = serial_nos[0]
si.update_stock = 1
si.insert()
si.submit()
@@ -453,10 +474,10 @@ class TestPOSInvoice(unittest.TestCase):
cost_center="Main - _TC",
item=se.get("items")[0].item_code,
rate=1000,
serial_no=[serial_nos[0]],
do_not_save=1,
)
pos2.get("items")[0].serial_no = serial_nos[0]
pos2.append(
"payments", {"mode_of_payment": "Bank Draft", "account": "_Test Bank - _TC", "amount": 1000}
)
@@ -473,7 +494,7 @@ class TestPOSInvoice(unittest.TestCase):
cost_center="Main - _TC",
expense_account="Cost of Goods Sold - _TC",
)
serial_nos = se.get("items")[0].serial_no + "wrong"
serial_nos = get_serial_nos_from_bundle(se.get("items")[0].serial_and_batch_bundle)[0] + "wrong"
pos = create_pos_invoice(
company="_Test Company",
@@ -486,14 +507,13 @@ class TestPOSInvoice(unittest.TestCase):
item=se.get("items")[0].item_code,
rate=1000,
qty=2,
serial_nos=[serial_nos],
do_not_save=1,
)
pos.get("items")[0].has_serial_no = 1
pos.get("items")[0].serial_no = serial_nos
pos.insert()
self.assertRaises(frappe.ValidationError, pos.submit)
self.assertRaises(frappe.ValidationError, pos.insert)
def test_value_error_on_serial_no_validation(self):
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item
@@ -504,7 +524,7 @@ class TestPOSInvoice(unittest.TestCase):
cost_center="Main - _TC",
expense_account="Cost of Goods Sold - _TC",
)
serial_nos = se.get("items")[0].serial_no
serial_nos = get_serial_nos_from_bundle(se.get("items")[0].serial_and_batch_bundle)
# make a pos invoice
pos = create_pos_invoice(
@@ -517,11 +537,11 @@ class TestPOSInvoice(unittest.TestCase):
cost_center="Main - _TC",
item=se.get("items")[0].item_code,
rate=1000,
serial_no=[serial_nos[0]],
qty=1,
do_not_save=1,
)
pos.get("items")[0].has_serial_no = 1
pos.get("items")[0].serial_no = serial_nos.split("\n")[0]
pos.set("payments", [])
pos.append(
"payments", {"mode_of_payment": "Cash", "account": "Cash - _TC", "amount": 1000, "default": 1}
@@ -547,12 +567,12 @@ class TestPOSInvoice(unittest.TestCase):
cost_center="Main - _TC",
item=se.get("items")[0].item_code,
rate=1000,
serial_no=[serial_nos[0]],
qty=1,
do_not_save=1,
)
pos2.get("items")[0].has_serial_no = 1
pos2.get("items")[0].serial_no = serial_nos.split("\n")[0]
# Value error should not be triggered on validation
pos2.save()
@@ -702,7 +722,7 @@ class TestPOSInvoice(unittest.TestCase):
)
if not frappe.db.get_single_value("Selling Settings", "validate_selling_price"):
frappe.db.set_value("Selling Settings", "Selling Settings", "validate_selling_price", 1)
frappe.db.set_single_value("Selling Settings", "validate_selling_price", 1)
item = "Test Selling Price Validation"
make_item(item, {"is_stock_item": 1})
@@ -748,16 +768,16 @@ class TestPOSInvoice(unittest.TestCase):
self.assertEqual(rounded_total, 400)
def test_pos_batch_item_qty_validation(self):
from erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle import (
BatchNegativeStockError,
)
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import (
create_batch_item_with_batch,
)
from erpnext.stock.serial_batch_bundle import SerialBatchCreation
create_batch_item_with_batch("_BATCH ITEM", "TestBatch 01")
item = frappe.get_doc("Item", "_BATCH ITEM")
batch = frappe.get_doc("Batch", "TestBatch 01")
batch.submit()
item.batch_no = "TestBatch 01"
item.save()
se = make_stock_entry(
target="_Test Warehouse - _TC",
@@ -767,16 +787,28 @@ class TestPOSInvoice(unittest.TestCase):
batch_no="TestBatch 01",
)
pos_inv1 = create_pos_invoice(item=item.name, rate=300, qty=1, do_not_submit=1)
pos_inv1.items[0].batch_no = "TestBatch 01"
pos_inv1 = create_pos_invoice(
item=item.name, rate=300, qty=1, do_not_submit=1, batch_no="TestBatch 01"
)
pos_inv1.save()
pos_inv1.submit()
pos_inv2 = create_pos_invoice(item=item.name, rate=300, qty=2, do_not_submit=1)
pos_inv2.items[0].batch_no = "TestBatch 01"
pos_inv2.save()
self.assertRaises(frappe.ValidationError, pos_inv2.submit)
sn_doc = SerialBatchCreation(
{
"item_code": item.name,
"warehouse": pos_inv2.items[0].warehouse,
"voucher_type": "Delivery Note",
"qty": 2,
"avg_rate": 300,
"batches": frappe._dict({"TestBatch 01": 2}),
"type_of_transaction": "Outward",
"company": pos_inv2.company,
}
)
self.assertRaises(BatchNegativeStockError, sn_doc.make_serial_and_batch_bundle)
# teardown
pos_inv1.reload()
@@ -785,9 +817,6 @@ class TestPOSInvoice(unittest.TestCase):
pos_inv2.reload()
pos_inv2.delete()
se.cancel()
batch.reload()
batch.cancel()
batch.delete()
def test_ignore_pricing_rule(self):
from erpnext.accounts.doctype.pricing_rule.test_pricing_rule import make_pricing_rule
@@ -838,18 +867,18 @@ class TestPOSInvoice(unittest.TestCase):
frappe.db.savepoint("before_test_delivered_serial_no_case")
try:
se = make_serialized_item()
serial_no = get_serial_nos(se.get("items")[0].serial_no)[0]
serial_no = get_serial_nos_from_bundle(se.get("items")[0].serial_and_batch_bundle)[0]
dn = create_delivery_note(item_code="_Test Serialized Item With Series", serial_no=serial_no)
dn = create_delivery_note(item_code="_Test Serialized Item With Series", serial_no=[serial_no])
delivered_serial_no = get_serial_nos_from_bundle(dn.get("items")[0].serial_and_batch_bundle)[0]
delivery_document_no = frappe.db.get_value("Serial No", serial_no, "delivery_document_no")
self.assertEquals(delivery_document_no, dn.name)
self.assertEqual(serial_no, delivered_serial_no)
init_user_and_profile()
pos_inv = create_pos_invoice(
item_code="_Test Serialized Item With Series",
serial_no=serial_no,
serial_no=[serial_no],
qty=1,
rate=100,
do_not_submit=True,
@@ -861,42 +890,6 @@ class TestPOSInvoice(unittest.TestCase):
frappe.db.rollback(save_point="before_test_delivered_serial_no_case")
frappe.set_user("Administrator")
def test_returned_serial_no_case(self):
from erpnext.accounts.doctype.pos_invoice_merge_log.test_pos_invoice_merge_log import (
init_user_and_profile,
)
from erpnext.stock.doctype.serial_no.serial_no import get_pos_reserved_serial_nos
from erpnext.stock.doctype.serial_no.test_serial_no import get_serial_nos
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item
frappe.db.savepoint("before_test_returned_serial_no_case")
try:
se = make_serialized_item()
serial_no = get_serial_nos(se.get("items")[0].serial_no)[0]
init_user_and_profile()
pos_inv = create_pos_invoice(
item_code="_Test Serialized Item With Series",
serial_no=serial_no,
qty=1,
rate=100,
)
pos_return = make_sales_return(pos_inv.name)
pos_return.flags.ignore_validate = True
pos_return.insert()
pos_return.submit()
pos_reserved_serial_nos = get_pos_reserved_serial_nos(
{"item_code": "_Test Serialized Item With Series", "warehouse": "_Test Warehouse - _TC"}
)
self.assertTrue(serial_no not in pos_reserved_serial_nos)
finally:
frappe.db.rollback(save_point="before_test_returned_serial_no_case")
frappe.set_user("Administrator")
def create_pos_invoice(**args):
args = frappe._dict(args)
@@ -926,6 +919,40 @@ def create_pos_invoice(**args):
pos_inv.set_missing_values()
bundle_id = None
if args.get("batch_no") or args.get("serial_no"):
type_of_transaction = args.type_of_transaction or "Outward"
if pos_inv.is_return:
type_of_transaction = "Inward"
qty = args.get("qty") or 1
qty *= -1 if type_of_transaction == "Outward" else 1
batches = {}
if args.get("batch_no"):
batches = frappe._dict({args.batch_no: qty})
bundle_id = make_serial_batch_bundle(
frappe._dict(
{
"item_code": args.item or args.item_code or "_Test Item",
"warehouse": args.warehouse or "_Test Warehouse - _TC",
"qty": qty,
"batches": batches,
"voucher_type": "Delivery Note",
"serial_nos": args.serial_no,
"posting_date": pos_inv.posting_date,
"posting_time": pos_inv.posting_time,
"type_of_transaction": type_of_transaction,
"do_not_submit": True,
}
)
).name
if not bundle_id:
msg = f"Serial No {args.serial_no} not available for Item {args.item}"
frappe.throw(_(msg))
pos_inv.append(
"items",
{
@@ -936,8 +963,7 @@ def create_pos_invoice(**args):
"income_account": args.income_account or "Sales - _TC",
"expense_account": args.expense_account or "Cost of Goods Sold - _TC",
"cost_center": args.cost_center or "_Test Cost Center - _TC",
"serial_no": args.serial_no,
"batch_no": args.batch_no,
"serial_and_batch_bundle": bundle_id,
},
)

View File

@@ -79,6 +79,7 @@
"warehouse",
"target_warehouse",
"quality_inspection",
"serial_and_batch_bundle",
"batch_no",
"col_break5",
"allow_zero_valuation_rate",
@@ -628,10 +629,11 @@
{
"fieldname": "batch_no",
"fieldtype": "Link",
"in_list_view": 1,
"hidden": 1,
"label": "Batch No",
"options": "Batch",
"print_hide": 1
"print_hide": 1,
"read_only": 1
},
{
"fieldname": "col_break5",
@@ -648,10 +650,12 @@
{
"fieldname": "serial_no",
"fieldtype": "Small Text",
"hidden": 1,
"in_list_view": 1,
"label": "Serial No",
"oldfieldname": "serial_no",
"oldfieldtype": "Small Text"
"oldfieldtype": "Small Text",
"read_only": 1
},
{
"fieldname": "item_tax_rate",
@@ -817,11 +821,19 @@
"fieldtype": "Check",
"label": "Has Item Scanned",
"read_only": 1
},
{
"fieldname": "serial_and_batch_bundle",
"fieldtype": "Link",
"label": "Serial and Batch Bundle",
"no_copy": 1,
"options": "Serial and Batch Bundle",
"print_hide": 1
}
],
"istable": 1,
"links": [],
"modified": "2022-11-02 12:52:39.125295",
"modified": "2023-03-12 13:36:40.160468",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Invoice Item",

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