Compare commits

..

725 Commits

Author SHA1 Message Date
Nabin Hait
8f057b4bac Merge branch 'version-13-pre-release' into version-13 2021-05-24 16:45:27 +05:30
Nabin Hait
10085580c8 bumped to version 13.3.1 2021-05-24 17:05:27 +05:50
Saqib
6368c976c7 fix: expected amount in pos closing payments table (#25737) 2021-05-24 16:44:38 +05:30
Nabin Hait
6bae78f410 Merge branch 'version-13-pre-release' into version-13 2021-05-17 11:36:29 +05:30
Nabin Hait
bc92ecb10f bumped to version 13.3.0 2021-05-17 11:56:29 +05:50
Nabin Hait
9ec0f11800 fix: renamed change log 2021-05-17 10:50:42 +05:30
Nabin Hait
2f403f1bcd fix: renamed change log 2021-05-17 10:50:26 +05:30
Nabin Hait
ad0b8fdd1e chore: Added change log for v13.3.0 2021-05-17 10:49:21 +05:30
rohitwaghchaure
e9f6c8cdb1 fix: validation message of quality inspection in purchase receipt (#25667) 2021-05-14 12:34:13 +05:30
rohitwaghchaure
0048418c46 Merge pull request #25703 from rohitwaghchaure/change-today-to-now-for-reposting-pre
fix: change today to now to get data for reposting
2021-05-13 17:44:27 +05:30
Rohit Waghchaure
a0a88a710e fix: change today to now to get data for reposting 2021-05-13 17:42:06 +05:30
Mohammad Hasnain Mohsin Rajan
7c6de1a8ac fix: bank statement import via google sheet (#25677)
* fix: change links in workspace

* fix: google sheet bank statement import

* chore: quotes

* fix: capitalization

* fix: typo

* chore: add translation
2021-05-13 17:28:49 +05:30
Deepesh Garg
6084baa9ae Merge pull request #25700 from deepeshgarg007/consolidated_report_param_fix_v13
fix: Parameter for get_filtered_list_for_consolidated_report in consolidated balance sheet
2021-05-13 15:23:53 +05:30
Deepesh Garg
8e748f8451 fix: Parameter for get_filtered_list_for_consolidated_report in consolidated balance sheet 2021-05-13 15:21:51 +05:30
rohitwaghchaure
c29c6ff9a7 Merge pull request #25692 from rohitwaghchaure/fixed-woocommerce-order-sync-issue-pre
fix: Woocommerce order sync issue
2021-05-12 23:09:33 +05:30
Rohit Waghchaure
fe68a0ff80 fix: Woocommerce order sync issue 2021-05-12 23:08:16 +05:30
Afshan
6578c045ca fix: Dialog variable assignment after definition in POS (#25680) 2021-05-12 17:41:50 +05:30
rohitwaghchaure
4ec0656f64 Merge pull request #25678 from rohitwaghchaure/fixed-new-fields-not-added-pre
fix: updated modified time in purchase invoice to pull new fields
2021-05-12 16:39:35 +05:30
Rohit Waghchaure
aaca8335f0 fix: updated modified time to pull new fields 2021-05-12 16:36:25 +05:30
Mohammad Hasnain Mohsin Rajan
dd1822ef58 fix: change links in workspace (#25673) 2021-05-12 13:01:53 +05:30
Nabin Hait
e38192cb6d fix: merge conflict 2021-05-11 11:15:09 +05:30
Deepesh Garg
d2520680bc fix: Error on applying TDS without party (#25632)
* fix: Error on applying TDS without party

* fix: Add placeholder value
2021-05-10 21:17:06 +05:30
Deepesh Garg
83f98f6992 Merge pull request #25653 from deepeshgarg007/tax_labels
fix: Client script breaking while settings tax labels
2021-05-10 18:24:02 +05:30
Deepesh Garg
9f0823a164 fix: Linting issues 2021-05-10 16:07:41 +05:30
Saqib
55d47a2baa fix(pos): UI fixes related to overflowing payment section (#25652)
* fix: additional fields overflowing in payment section

* fix: pos profile filter in pos opening dialog

* fix: item quantity pill
2021-05-10 15:59:37 +05:30
Deepesh Garg
13dfb9734c fix: Lable for transaction child tables 2021-05-10 15:38:32 +05:30
Deepesh Garg
1a48eb49cf fix: Client script breaking while settings tax labels 2021-05-10 14:37:10 +05:30
Ganga Manoj
f2eb8dd1d5 feat: Transaction Deletion Record (#25354)
Co-authored-by: Saqib <nextchamp.saqib@gmail.com>
2021-05-10 14:02:58 +05:30
Ankush Menat
6e179c3092 fix: sync shopify customer addresses (#25481) 2021-05-10 13:24:26 +05:30
Saqib
9226cd3932 feat(india): reduced rate of depreciation as per IT Act (#25648)
* feat(india): reduced rate of depreciation as per IT Act

* refactor: check date difference instead of month difference

* feat: add test for regional feature
2021-05-10 12:36:56 +05:30
Ganga Manoj
aa9e172091 feat: Add Create Expense Claim button in Delivery Trip (#25526)
* feat(Delivery Trip): Add employee_code field

* feat(Expense Claim): Add Delivery Trip Number field

* feat(Delivery Trip): Add Create Expense Claim button

* feat(Delivery Trip): Make Create Expense Claim button show up after save

* fix(Delivery Trip): Fix Sider issues

* fix(Delivery Trip): Display button after submit

* fix(Delivery Trip & Expense Claim): Rename new fields

* fix(Delivery Trip): Add button in refresh

* fix(Delivery Trip): Remove redundant line

* fix(Expense Claim): Display delivery_trip only if non-empty

* fix(Delivery Trip): Add test for Create Expense Claim

* fix(Delivery Trip): Fix Sider Issue

* fix(Delivery Trip): Only display Create Expense Claim if the driver is an employee

* fix(Delivery Trip): Fix test

* fix(Delivery Trip): Fix make_expense_claim()

* fix: sider

Co-authored-by: Saqib <nextchamp.saqib@gmail.com>
2021-05-08 17:15:33 +05:30
rohitwaghchaure
64bd4f27b8 Merge pull request #25611 from rohitwaghchaure/validation-to-check-duplicate-serial-nos
fix: added validation in stock entry to check duplicate serial nos
2021-05-07 23:30:27 +05:30
rohitwaghchaure
42fe07bd19 Merge pull request #25551 from rohitwaghchaure/fixed-total-stock-summary-report
fix: total stock summary report not working
2021-05-07 23:30:06 +05:30
rohitwaghchaure
1726ce547c Merge pull request #25471 from rohitwaghchaure/allow-to-receipt-same-serial-no
fix: allow to receive same serial numbers multiple times
2021-05-07 23:27:50 +05:30
Alan
c6dc9eaf2e feat!: add pick batch button (#25413)
* feat!: add pick batch button

BREAKING CHANGE: replaces setup_serial_no with setup_serial_or_batch_no.

* refactor: use setup_serial_or_batch_no instead of setup_serial_no

* refactor: use setup_serial_or_batch_no instead of setup_serial_no

* refactor: use setup_serial_or_batch_no instead of setup_serial_no

* style: add sider review changes

* refactor: make consice, extract function

* refactor: camel to snake casing
2021-05-07 20:30:04 +05:30
Ankush Menat
90e671905a chore: replace assertEquals with alias assertEqual (#25613)
* chore: replace assertEquals with alias assertEqual

assertEquals has been deprecated.

ref: https://docs.python.org/3/library/unittest.html#deprecated-aliases

* chore: sider fixes
2021-05-07 20:28:51 +05:30
Ankush Menat
e28165ea87 fix: force https for shopify webhook registration (#25630) 2021-05-07 20:27:51 +05:30
Anupam Kumar
da7fefe29d fix: timesheet filter date exclusive issue (#25626) 2021-05-07 20:26:50 +05:30
Saqib
27cf19a19f feat(pos): show POS reserved stock in stock projected qty report (#25593)
* feat(pos): consider POS reserved stock in stock projected qty report

* chore: remove unwanted string formats
2021-05-07 13:37:42 +05:30
Ganga Manoj
5618ce3852 fix(Material Request): Add 'Partially Received' to Status drop-down list (#24857)
Co-authored-by: Ganga Manoj <ganga_manoj@Gangas-MacBook-Air.local>
Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2021-05-07 13:35:09 +05:30
Rucha Mahabal
062d30146f fix: Include search fields in Project Link field query (#25505)
* fix: Include search fields in Project Link field query

* fix: add project_name to Project search fields
2021-05-07 13:31:14 +05:30
Umair Sayed
7f79d463f6 fix: Stock and Accounts Settings form refactor (#25534)
* stock and accounts settings page

* fix: Stock and accounts settings page cleanup

Co-authored-by: Umair Sayed <umairsayed@Umairs-MacBook-Air.local>
2021-05-07 12:28:57 +05:30
Shariq Ansari
735fbdc350 fix: Updating Standard Notification's channel field (#25564) 2021-05-07 12:26:32 +05:30
Deepesh Garg
00e00e4e90 fix: Report summary showing inflated values when values are accumulated in Group Company (#25577)
* fix: Report summary showing inflated values when values are accumullated in Group Company

* fix: Remove extra space

* fix: Translate strings

* fix: Remove unintended changes
2021-05-07 12:16:44 +05:30
Shadrak Gurupnor
f648d2d7c4 fix: added tax_types list (#25587) 2021-05-07 12:15:19 +05:30
Ankush Menat
996f7e53a1 fix: update shopify api version (#25600) 2021-05-07 12:14:14 +05:30
Anuja Pawar
f132ed4335 fix: update item level cost center from POS (#25609) 2021-05-07 12:11:09 +05:30
Alan
0e0de6baa1 fix: prevent spurious defaults for items when making prec from dnote (#25559)
* fix: prevent spurious defaults for items when making prec from dnote

* refactor: make concise, use dict comp
2021-05-07 11:40:02 +05:30
Noah Jacob
4ecae62194 fix: added is_stock_item filter (#25530) 2021-05-06 19:42:01 +05:30
Nabin Hait
ec2ba6bc1f Merge branch 'version-13-pre-release' into version-13 2021-05-06 19:18:17 +05:30
Nabin Hait
ae18efaa0a bumped to version 13.2.1 2021-05-06 19:38:17 +05:50
Nabin Hait
0e41295c0e perf: Performance enhancement on setup wizard (#25606)
* perf: Performance enhancement on setup wizard

* fix: create departments without updating nsm
2021-05-06 19:14:06 +05:30
Nabin Hait
134eaa5786 perf: Performance enhancement on setup wizard (#25605)
* perf: Performance enhancement on setup wizard

* fix: create departments without updating nsm
2021-05-06 19:13:54 +05:30
Rohit Waghchaure
695becdd05 fix: added validation in stock entry to check duplicate serial nos 2021-05-06 18:03:32 +05:30
rohitwaghchaure
dc6233b703 Merge pull request #25541 from rohitwaghchaure/fixed-incorrect-serial-no-set
fix: serial no changed after saving stock reconciliation
2021-05-06 17:44:36 +05:30
Saqib
92cefd5655 feat(pos): ability to retry on pos closing failure (#25604)
* feat(pos): ability to retry on pos closing failure

* fix: sider issues

* fix: sider issues

* fix: mark all queued closing entry as failed

* feat: add headline message
2021-05-06 17:03:16 +05:30
Saqib
900a8fb21a feat(pos): ability to retry on pos closing failure (#25595)
* feat(pos): ability to retry on pos closing failure

* fix: sider issues

* fix: sider issues

* fix: mark all queued closing entry as failed

* feat: add headline message
2021-05-06 17:02:47 +05:30
Deepesh Garg
daf6c124a9 fix: Check if payment schedule exists 2021-05-06 16:47:02 +05:30
Deepesh Garg
be66ee9723 fix: Check if payment schedule exits before updating label 2021-05-06 16:46:55 +05:30
Deepesh Garg
a0ed517c85 fix: function call to update payment schedule labels 2021-05-06 16:46:47 +05:30
Sagar Vora
f43a86d90f perf: significant reduction in time taken to save a delivery note (#25475) 2021-05-06 16:40:06 +05:30
Saqib
d502f76319 feat(e-invoicing): e-way bill validity field (#25555) 2021-05-06 16:10:55 +05:30
Deepesh Garg
8a1f86db16 Merge pull request #25582 from deepeshgarg007/this_variable
fix: function call to update payment schedule labels
2021-05-06 15:50:47 +05:30
Deepesh Garg
9dd0a26e92 Merge pull request #25598 from deepeshgarg007/payment_reco_invoice_fix
fix: Invoices not getting fetched during payment reconciliation
2021-05-06 15:49:19 +05:30
rohitwaghchaure
7ed531611b Merge pull request #25588 from 18alantom/fix-check-schedule-date
fix: check for None in item.schedule_date before setting
2021-05-06 14:04:14 +05:30
rohitwaghchaure
180ba1dfc9 Merge pull request #25590 from 18alantom/fix-use-get-serial-nos
fix: use get_serial_nos for splitting
2021-05-06 14:03:15 +05:30
Rohit Waghchaure
bb3e5d00f4 fix: allow to receive same serial numbers multiple times 2021-05-06 12:38:35 +05:30
Deepesh Garg
85b675a554 fix: Invoices not fetch during payment reconciliation 2021-05-05 20:57:31 +05:30
Deepesh Garg
ffea9d4126 fix: Check if payment schedule exists 2021-05-05 12:28:40 +05:30
18alantom
136eb30081 fix: use get_serial_nos for splitting 2021-05-05 12:26:29 +05:30
Deepesh Garg
1bb7bb74ad fix: Check if payment schedule exits before updating label 2021-05-05 12:19:57 +05:30
18alantom
2a20a03c28 fix: check for None in item.schedule_date before setting 2021-05-05 11:59:15 +05:30
rohitwaghchaure
8be414873b Merge pull request #25575 from rohitwaghchaure/fixed-stock-balance-report-and-batchwise-report
fix: stock balance and batch-wise balance history report showing different closing stock
2021-05-05 10:04:23 +05:30
Deepesh Garg
04923d6a65 fix: function call to update payment schedule labels 2021-05-04 21:01:12 +05:30
Asharam Seervi
18ad15ed16 fix: designation insufficient permission on lead doctype. (#25331) 2021-05-04 19:28:07 +05:30
Afshan
eebc6e9277 refactor: Show item's full name on hover over item in POS (#25554)
Co-authored-by: Saqib <nextchamp.saqib@gmail.com>
2021-05-04 17:05:12 +05:30
Rushabh Mehta
5fc4f1e37d Merge pull request #25238 from alyf-de/datev_fixes
feat: Improve DATEV export
2021-05-04 15:38:57 +05:30
Rohit Waghchaure
ba8dc1ffbd fix: stock balance and batchwise balance history report showing different closing stock 2021-05-04 15:03:10 +05:30
Saqib
384f4b5b7e fix: can't open general ledger from consolidated financial report (#25542) 2021-05-04 12:33:49 +05:30
Saqib
1e554378c7 fix(pos): incorrect expense account set in pos invoice (#25571) 2021-05-04 12:28:24 +05:30
Saqib
076020643d fix: empty payment term column in accounts receivable report (#25556) 2021-05-04 12:26:49 +05:30
18alantom
308905b1be fix: semgrep, refactor default mutable dict 2021-05-04 11:46:13 +05:30
18alantom
e36f303042 fix: use percent string templates for db.sql calls 2021-05-04 11:46:13 +05:30
barredterra
24e2cc9107 Merge branch 'develop' into datev_fixes 2021-05-03 18:19:28 +02:00
Suraj Shetty
ca37380d2e Merge branch 'develop' of github.com:frappe/erpnext into develop 2021-05-03 19:44:22 +05:30
Rucha Mahabal
f1bdfac7a8 fix: Employee Separation (#25503)
* fix: Employee Separation

- add ignore_mandatory flag for project creation

- form clean-up

* fix: Employee Separation test
2021-05-03 18:37:00 +05:30
rohitwaghchaure
1f4df80565 Merge pull request #25531 from noahjacob/fix_mr_filter
fix: updated item filters for material request
2021-05-03 18:36:25 +05:30
rohitwaghchaure
88734eea14 Merge pull request #25557 from rohitwaghchaure/increased-timeout-of-stoc-reco
fix: stock reconciliation getting time out error during submission
2021-05-03 18:25:33 +05:30
Rohit Waghchaure
8f34ca4ac6 fix: stock reconciliation getting time out error during submission 2021-05-03 15:32:13 +05:30
Saqib
cdc99cdd49 fix(pos): incorrect expense account set in pos invoice (#25543) 2021-05-03 11:54:55 +05:30
rohitwaghchaure
9cc7c294e7 Update stock_reconciliation.py 2021-05-03 10:25:53 +05:30
Deepesh Garg
84ec295b43 Merge pull request #25546 from deepeshgarg007/loan_schedule_fixes
fix: Minor fixes in loan
2021-05-02 22:35:34 +05:30
Rohit Waghchaure
6a5a380c07 fix: total stock summary report not working 2021-05-02 18:02:28 +05:30
Rohit Waghchaure
35d4829383 fix: serial no changed after saving stock reconciliation 2021-05-02 17:57:28 +05:30
rohitwaghchaure
5f177aaeaa Merge pull request #25545 from rohitwaghchaure/fixed-depost-withdrwal-values-has-not-updated
fix: rename field has not updated value of deposit and withdrawal fields
2021-05-02 17:54:22 +05:30
Deepesh Garg
c571141c1f fix: Test cases 2021-05-02 15:31:04 +05:30
Deepesh Garg
824f089569 fix: Auto write off on loan closure 2021-05-01 22:07:13 +05:30
Deepesh Garg
1efafb3ce8 fix: Do not roundoff balance amount 2021-05-01 21:52:43 +05:30
Rohit Waghchaure
2fb573781d fix: rename field has not updated value of deposit and withdrawal fields 2021-05-01 17:56:40 +05:30
Nabin Hait
0c7448fc41 fix: Fixed merge conflict 2021-05-01 14:54:22 +05:30
Nabin Hait
a2fcca85a5 fix: Fixed merge conflict 2021-05-01 14:53:13 +05:30
Nabin Hait
d8cd5a95cb bumped to version 13.2.0 2021-05-01 15:12:44 +05:50
Nabin Hait
3c788f0325 chore: Add release note for v13.2.0 2021-05-01 14:42:30 +05:30
rohitwaghchaure
2e38f1514f fix: stock ledger entry created against draft stock entry (#25539) 2021-05-01 13:53:46 +05:30
rohitwaghchaure
00ea336b52 fix: stock ledger entry created against draft stock entry (#25540) 2021-05-01 13:53:39 +05:30
Afshan
1fd1e2bb60 fix: fieldname when updating docfield property (#25517) 2021-04-30 18:41:26 +05:30
Afshan
e91b0021ac fix: fieldname when updating docfield property (#25516) 2021-04-30 18:41:19 +05:30
Afshan
5a4615fd4e fix: allow to cancel loan with cancelled replayment entry (#25508) 2021-04-30 18:40:43 +05:30
Nabin Hait
a19c6a9278 fix: Fetch total stock at company in PO (#25533) 2021-04-30 18:38:49 +05:30
Nabin Hait
da0ba15cbf fix: Fetch total stock at company in PO (#25532) 2021-04-30 18:38:41 +05:30
Deepesh Garg
89120695a6 Merge pull request #25529 from deepeshgarg007/psoa_fixes_v13_pre_release
fix: Ageing errors in PSOA
2021-04-30 16:33:26 +05:30
Raffael Meyer
07a081d8ac Merge branch 'develop' into datev_fixes 2021-04-30 12:25:40 +02:00
noahjacob
a90c81626f fix: updated item filters for material request 2021-04-30 15:49:36 +05:30
Deepesh Garg
88d40e8dc4 fix: Remove extra space 2021-04-30 15:33:33 +05:30
Deepesh Garg
1deef5229e fix: Linting and translation issues 2021-04-30 15:20:55 +05:30
Deepesh Garg
bd5ee7d725 fix: Use party account currency 2021-04-30 15:20:45 +05:30
Deepesh Garg
9cbca06f4e fix: Updated filters for process statement of accounts 2021-04-30 15:20:31 +05:30
Deepesh Garg
303f6d2d36 Merge branch 'version-13-pre-release' of https://github.com/frappe/erpnext into psoa_fixes_v13_pre_release 2021-04-30 15:17:07 +05:30
Deepesh Garg
178938b2f0 fix: Ageing errors in PSOA 2021-04-30 15:14:24 +05:30
Deepesh Garg
3d9fa2b8de Merge pull request #25528 from Anuja-pawar/fix_allocated_amt_pre_release
fix: update allocated amount after paid amount is changed in PE version13 pre release
2021-04-30 14:42:18 +05:30
Deepesh Garg
c4231c72a6 Merge pull request #25524 from aerele/develop
fix: List invoices in Payment Reconciliation Payment
2021-04-30 14:15:33 +05:30
Anuja P
435e93bda9 fix: allocated amount change wrt paid amount change 2021-04-30 13:52:48 +05:30
Deepesh Garg
8aa57953ee Merge pull request #25490 from deepeshgarg007/psoa_fixes_v2
fix: Ageing errors in PSOA
2021-04-30 13:07:00 +05:30
Deepesh Garg
cd9fa61659 Merge pull request #25521 from ernestoruiz89/patch-4
fix: Make strings translatable
2021-04-30 12:58:26 +05:30
Deepesh Garg
26920b439a Merge pull request #25394 from meike289/feature/check-field-subscription-invoice
feat: new check field in subscriptions for (not) submitting invoices
2021-04-30 12:32:45 +05:30
Deepesh Garg
0dc411951e Merge pull request #25438 from nextchamp-saqib/round-off-diff-allowance
fix: ignore fraction difference while making round off gl entry
2021-04-30 11:11:21 +05:30
Deepesh Garg
1ec53c1cf2 Merge pull request #25518 from nextchamp-saqib/payment-term-amount-currency-fix-v13
fix: payment amount showing in foreign currency
2021-04-30 11:09:58 +05:30
Deepesh Garg
338a006e28 Merge pull request #25515 from Anuja-pawar/fix_PE_allocated_amt
fix: update Allocated amount after Paid Amount is changed in PE
2021-04-30 11:08:51 +05:30
Vignesh S
7783a56c08 fix: List invoices in Payment Reconciliation Payment
Invoices are not listed in the Payment Reconciliation Payment table due to a typo in the code
2021-04-29 22:39:42 +05:30
Ernesto Ruiz
76e1e68cf4 fix: Make strings translatable
Make strings translatable
2021-04-29 08:24:56 -06:00
Saqib Ansari
3e83542360 fix: sider issues 2021-04-29 18:12:47 +05:30
Saqib
2bde1baa38 fix: remove print statement 2021-04-29 18:12:42 +05:30
Saqib Ansari
6dd1c5cf92 refactor: remove extra fields 2021-04-29 18:12:36 +05:30
Saqib Ansari
3a5ecb7587 fix: test 2021-04-29 18:12:32 +05:30
Saqib Ansari
973afeac3c feat: set dynamic labels for payment schedule fields 2021-04-29 18:12:27 +05:30
Saqib Ansari
a91eebf6aa feat: base payment amount in payment schedule 2021-04-29 18:12:23 +05:30
Saqib Ansari
e70d9c925c fix: payment amount showing in foreign currency 2021-04-29 18:12:17 +05:30
Anuja Pawar
07fb98b91d Merge branch 'develop' into fix_PE_allocated_amt 2021-04-29 17:17:21 +05:30
Anuja P
dd1e7624bf fix: changing paid amount should change allocated amount 2021-04-29 17:00:59 +05:30
Deepesh Garg
7bf25b4cef Merge pull request #25292 from nextchamp-saqib/payment-term-amount-display-currency-fix
fix: payment amount showing in foreign currency
2021-04-29 16:33:01 +05:30
Mohammad Hasnain Mohsin Rajan
0dc00219e8 fix: coveralls different services for different events (#25513) 2021-04-29 15:21:16 +05:30
Saqib Ansari
6fb417590f fix: sider issues 2021-04-29 14:05:20 +05:30
Deepesh Garg
3386d4948e Merge pull request #25507 from AfshanKhan/fix-cancel-loan
fix: allow to cancel loan with cancelled repayment entry
2021-04-29 12:31:52 +05:30
Saqib
83e3820575 fix: remove print statement 2021-04-29 12:21:56 +05:30
Noah Jacob
dc086dd52f fix: item stock levels displaying inconsistently (#25506)
* fix: fixed stock levels dashboard not displaying after any interactions

* fix: minor translation fix
2021-04-29 11:03:27 +05:30
Afshan
ab052599c0 fix: allow to cancel loan with cancelled replayment entry 2021-04-28 20:21:04 +05:30
gavin
3b1ae4eb90 Merge pull request #25501 from ankush/remove_frappe_dep
chore: remove frappe from requirements.txt
2021-04-28 17:38:35 +05:30
Ankush Menat
64a38f52cf chore: remove frappe from requirements.txt
Due to recent changes in pip dependency resolver, in some random cases
pip thinks frappe is not installed and tries to fetch it from pypi,
which results in errors like #25496

Until a better solution is available, frappe should not be part
of requirements.txt
2021-04-28 16:56:10 +05:30
Raffael Meyer
d75b4c37a3 Merge branch 'develop' into feature/check-field-subscription-invoice 2021-04-28 12:38:49 +02:00
Raffael Meyer
a949480acf fix: add translation to make semgrep pass 2021-04-28 12:38:23 +02:00
Saqib Ansari
44b07e4ef5 refactor: remove extra fields 2021-04-28 15:11:57 +05:30
Saqib Ansari
da5b55c4f5 fix: test 2021-04-28 14:55:33 +05:30
Saqib Ansari
3f7ec95af8 Merge branch 'develop' of https://github.com/frappe/erpnext into payment-term-amount-display-currency-fix 2021-04-28 14:45:27 +05:30
Saqib Ansari
aa4f750d8c fix: test 2021-04-28 14:42:49 +05:30
Saqib Ansari
3f53b87379 Merge branch 'develop' of https://github.com/frappe/erpnext into round-off-diff-allowance 2021-04-28 14:34:51 +05:30
Mohammad Hasnain Mohsin Rajan
c9187b00af fix: change coveralls version (#25499) 2021-04-28 13:32:27 +05:30
Nabin Hait
f085c89994 Merge branch 'version-13-hotfix' into version-13 2021-04-27 20:08:01 +05:30
Nabin Hait
b7fea12cdf Merge branch 'version-13' into develop 2021-04-27 20:08:01 +05:30
Nabin Hait
3e5c6424ed bumped to version 13.1.1 2021-04-27 20:28:01 +05:50
Rucha Mahabal
a86a51f020 fix(HR): Permission error while adding weekly holidays (#25450) 2021-04-27 20:01:49 +05:30
Saqib
7b3dd3585b fix: unexpected keyword argument 'merge_logs' (#25489)
* fix: unexpected keyword arguement 'merge_logs'

* fix: reference error

* fix: test
2021-04-27 20:01:08 +05:30
Saqib
ad4365eb0e fix: unexpected keyword argument 'merge_logs' (#25489)
* fix: unexpected keyword arguement 'merge_logs'

* fix: reference error

* fix: test
2021-04-27 20:00:21 +05:30
Deepesh Garg
8a1e5e189c fix: Ageing errors in PSOA 2021-04-27 16:57:34 +05:30
barredterra
5b9d3f15a2 docs: replace whitespace indent in docstring with tabs 2021-04-27 12:34:10 +02:00
Raffael Meyer
b2be91e731 Merge branch 'develop' into datev_fixes 2021-04-27 12:21:14 +02:00
rohitwaghchaure
b9078a0c86 Merge pull request #25126 from rohitwaghchaure/purchase-invoice-to-purchase-receipt-develop
feat: purchase receipt creation from purchase invoice
2021-04-27 09:56:28 +05:30
Deepesh Garg
ebc6c51abe Merge pull request #25384 from deepeshgarg007/psoa_fixes
fix: Updated filters for process statement of accounts
2021-04-26 22:58:42 +05:30
Afshan
df06e49e0c feat: enable custom field search on POS (#25421)
* feat: multi lingual item search in POS

* fix: limit the options for selection and broken down funtion for geting condition
2021-04-26 22:48:13 +05:30
Anurag Mishra
7f1b2de74d feat: Employee Referral (#24997)
* feat: Employee referal design and status sync

* feat: create job Applicant and linked Document

* feat: Added list view indicator

* chore: formatted file

* feat: Addedd Employee Referral form Dashboard

* feat: pay compensation via additional salary

* test: Employee Rreferral

* Update erpnext/hr/doctype/employee_advance/employee_advance.js

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>

* fix: changes requested

* fix: changes requested

* fix: sider

* fix: translation

* fix: test

* feat: added to Dashboard

* fix: changes

* chore: clean-up Employee Referral form

- fix labels

- fix full name field

- fix failing test

- set title for Employee Referral form

- set fields in List View and Standard Filter

* feat: option to add a resume link

- copy resume and resume link from Employee Referral to Job Applicant

* fix: multiple fixes

- confirm before rejecting employee referral

- set primary actions for custom buttons

- Validations for additional salary against employee referrals with status as accepted only

- fix list view indicators

- code formatting style

* feat: Add field to track Referral Bonus Payment Status

- fix visibility of additional salary button

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2021-04-26 22:23:48 +05:30
Nabin Hait
2ddca77243 Merge branch 'develop' into version-13-pre-release 2021-04-26 21:12:07 +05:30
Saqib
b643776c53 feat(e-invoicing): auto calculate distance for e-way bill generations (#25480) 2021-04-26 17:12:20 +05:30
Rucha Mahabal
1608658700 Merge pull request #25209 from NagariaHussain/employee-util-report
feat: Employee Hours Utilization Report
2021-04-26 17:04:35 +05:30
Saqib
34ce4edf29 fix: cannot scan spacebar character in pos (#25479) 2021-04-26 16:38:57 +05:30
Rucha Mahabal
d5ca9474ce fix: add employee name in report data 2021-04-26 16:10:06 +05:30
Rucha Mahabal
926a9aed58 Merge branch 'develop' into employee-util-report 2021-04-26 16:03:39 +05:30
Rucha Mahabal
7a84d76489 fix: tests 2021-04-26 16:03:10 +05:30
Ankush Menat
9178d95cca fix: can not create item variants (#25433)
* fix: item_code assigned to function returning None

* fix: ignore has_variants and attributes in variant

* fix: patch to remove has_variants and attributes

* chore: fix whitespace in translation
2021-04-26 15:37:17 +05:30
Jannat Patel
616f1d3624 fix: issue in project custom status (#25452) 2021-04-26 15:35:49 +05:30
Sagar Vora
71342320ce fix(Italy): multiple fixes in import supplier invoice (#25466)
* fix(Italy): remove incorrect method, use defined variable

* fix: show attach section after save; use db_set
2021-04-26 15:32:28 +05:30
Ankush Menat
c2de4f6b35 chore: update snyk (#25477) 2021-04-26 15:28:17 +05:30
Deepesh Garg
4c8d15b487 fix: Incorrect GL Entry validation (#25474)
* fix: Incorrect GL Entry validation

* fix: Add validation for party accounts

* fix: Scrub labels

* fix: Translation
2021-04-26 15:24:34 +05:30
Deepesh Garg
ab7664e595 Merge pull request #25444 from deepeshgarg007/gstr_backward_compatiability
fix: Backward compatibility for GSTR-1 report
2021-04-26 15:09:55 +05:30
Deepesh Garg
0b9aa58b81 Merge branch 'develop' of https://github.com/frappe/erpnext into psoa_fixes 2021-04-26 14:51:20 +05:30
Deepesh Garg
968ec110f3 fix: Linting and translation issues 2021-04-26 14:51:00 +05:30
Deepesh Garg
cac3fd3a24 Merge pull request #25460 from Anuja-pawar/fix_allocated_amt_in_PE
fix: to update Allocated amount after Paid Amount is changed in PE
2021-04-26 13:29:17 +05:30
Rucha Mahabal
4716ebea5a feat: Add % Utilization (Billed Only)
- Added billed utilization metric in report summary
2021-04-26 11:40:26 +05:30
Anuja Pawar
fee9a56d4e Merge branch 'develop' into fix_allocated_amt_in_PE 2021-04-26 11:36:10 +05:30
Anuja P
802518b8ac Merge branch 'fix_allocated_amt_in_PE' of https://github.com/Anuja-pawar/erpnext into fix_allocated_amt_in_PE 2021-04-26 11:34:33 +05:30
Anuja P
f74d8d2e16 fix: suggested changes 2021-04-26 11:31:51 +05:30
Rucha Mahabal
2a1a472371 chore: clean-up
- set default date filters for last month instead of year

- added abbreviations for columns to use them in the metrics labels
2021-04-26 11:18:32 +05:30
Shadrak Gurupnor
b9d4719285 fix: circular loop in project task (#25454)
* fix: circular loop in project task
2021-04-26 11:14:07 +05:30
Rucha Mahabal
0decc2b66a fix: validate Standard Working Hours
- use standard working hours in metrics calculation
2021-04-26 11:00:54 +05:30
Rucha Mahabal
b7a7e1b11a Merge branch 'develop' into employee-util-report 2021-04-26 10:25:42 +05:30
Rucha Mahabal
9d6520d4a7 Merge pull request #24944 from pateljannat/profitability-report
feat: Project Profitability Report
2021-04-26 10:02:36 +05:30
Rucha Mahabal
e939da982e Merge branch 'develop' into profitability-report 2021-04-26 09:17:12 +05:30
Rucha Mahabal
2a25c7505e fix: report column widths 2021-04-25 20:29:14 +05:30
Walstan Baptista
4a805b5622 chore: frappe.whitelist for doc methods (#25465) 2021-04-24 14:23:08 +05:30
Anuja Pawar
dc215ec08d Merge branch 'develop' into fix_allocated_amt_in_PE 2021-04-23 22:06:15 +05:30
Rucha Mahabal
e63f3b2f36 fix: standard working hours message and link for HR Settings 2021-04-23 20:33:42 +05:30
Rucha Mahabal
184317d5bd fix(HR): Permission error while adding weekly holidays (#25450) 2021-04-23 20:03:50 +05:30
Anuja P
dc599e0164 fix: to update Allocated amount after Paid Amount is changed 2021-04-23 19:24:53 +05:30
gavin
1b1c1bcbd0 Merge pull request #25455 from revant/docs-docker-readme
docs: add docker repo link in README
2021-04-23 16:31:41 +05:30
gavin
62d2df5815 docs: Add Frappe reference in Containerized Install section 2021-04-23 16:31:13 +05:30
Saqib Ansari
c5c9f9a941 feat: set dynamic labels for payment schedule fields 2021-04-23 15:34:58 +05:30
Saqib Ansari
d552fe6778 feat: base payment amount in payment schedule 2021-04-23 14:46:52 +05:30
Suraj Shetty
52ea6b126b Revert "fix: email digest user not found"
This reverts commit 188657d05a.
2021-04-23 14:14:47 +05:30
Saqib Ansari
242242c43f Merge branch 'develop' of https://github.com/frappe/erpnext into payment-term-amount-display-currency-fix 2021-04-23 13:54:13 +05:30
Revant Nandgaonkar
68b514b1f5 docs: add docker repo link in README 2021-04-23 13:06:13 +05:30
meike289
8787ebf83d Apply suggestions from code review
Co-authored-by: Ankush Menat <ankushmenat@gmail.com>
2021-04-23 08:06:29 +02:00
Rucha Mahabal
373e248e9f fix(patch): lab module patch fix (#25447) (#25449)
* fix(patch): lab module patch fix

* fix: param

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>

Co-authored-by: Anoop <3326959+akurungadam@users.noreply.github.com>
2021-04-22 22:47:39 +05:30
Anoop
c21ce42559 fix(patch): lab module patch fix (#25447)
* fix(patch): lab module patch fix

* fix: param

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2021-04-22 22:44:44 +05:30
Deepesh Garg
eed60bf035 fix: Backward compatibility for GSTR-1 report 2021-04-22 17:11:22 +05:30
pateljannat
84ef7419da fix: sider 2021-04-22 16:31:16 +05:30
Saqib
3d4acf9e5c fix: permission error after submitting exchange rate revaluation (#25432) 2021-04-22 16:16:03 +05:30
Rucha Mahabal
e3b8057eb4 fix: Laboratory Module patch (#25431) 2021-04-22 16:11:17 +05:30
Rucha Mahabal
3847452b60 fix: Laboratory Module patch (#25436) 2021-04-22 16:11:01 +05:30
pateljannat
2004fec8eb fix: removed multicurrency 2021-04-22 14:52:36 +05:30
Saqib
19b73968d7 fix(pos): validations & minor ui issues (#25351)
* fix: pos print format

* fix: stock validation on pos invoice creation
2021-04-22 13:38:20 +05:30
Saqib Ansari
b0e160ff78 fix: ignore fraction difference while making round off gl entry 2021-04-22 13:23:50 +05:30
pateljannat
ba6ad7f5be fix: escape for format and msg for working hours if not set 2021-04-22 11:19:44 +05:30
Mohammad Hasnain Mohsin Rajan
7f932cfb30 fix: display reconcile tool when closing balance 0 (#25417)
Co-authored-by: Saqib <nextchamp.saqib@gmail.com>
2021-04-22 04:53:09 +05:30
Alan
157b388209 fix: change subcontracted item display (#25425) 2021-04-21 21:00:22 +05:30
Ernesto Ruiz
090177494d fix: Make strings translatable
Make strings translatable
2021-04-21 09:04:06 -06:00
Deepesh Garg
e5e20c50a9 Merge branch 'develop' into purchase-invoice-to-purchase-receipt-develop 2021-04-21 19:09:41 +05:30
pateljannat
485464d1f4 fix: added back a hook 2021-04-21 18:04:58 +05:30
Nabin Hait
db76612462 Merge branch 'version-13-pre-release' into version-13 2021-04-21 12:34:49 +05:30
Nabin Hait
29d4ac13ac Merge branch 'version-13' into develop 2021-04-21 12:34:49 +05:30
Nabin Hait
c3b7c1b998 bumped to version 13.1.0 2021-04-21 12:54:49 +05:50
pateljannat
a92560d79f Merge branch 'profitability-report' of https://github.com/pateljannat/erpnext into profitability-report 2021-04-21 12:32:31 +05:30
pateljannat
039a5a829d fix: dynamic values for tests 2021-04-21 12:32:25 +05:30
Nabin Hait
cb92ead061 fix: Added Change Log 2021-04-21 11:22:35 +05:30
Jannat Patel
d106db60ad Merge branch 'develop' into profitability-report 2021-04-21 09:10:49 +05:30
Ernesto Ruiz
66250351d2 fix: Add transtlation function to strings
Add transtlation function to strings
2021-04-20 14:35:14 -06:00
Deepesh Garg
e7895cea71 Merge pull request #25393 from deepeshgarg007/loan_manager_amend
fix: Add amend perm for loan and system manager for loan doctypes
2021-04-20 22:21:52 +05:30
Raffael Meyer
48cd4de0d2 Merge branch 'develop' into feature/check-field-subscription-invoice 2021-04-20 16:15:01 +02:00
Deepesh Garg
6d88cf9ede Merge branch 'develop' into loan_manager_amend 2021-04-20 19:08:31 +05:30
pateljannat
cbdcfb4873 fix: multicurrency 2021-04-20 17:53:41 +05:30
Syed Mujeer Hashmi
704ec132b7 feat:Inpatient Occupancy Table Editable for Healthcare Admin (#24989)
Make Admitted datetime and  Discharge Datetime editable along with
Inaptient Occupancy Service Unit, Check_In and Check_out time.

Signed-off-by: Syed Mujeer Hashmi <mujeerhashmi@4csolutions.in>

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2021-04-20 16:39:46 +05:30
gavin
59a2ebd2f4 Merge pull request #25156 from Alchez/feat-py3-dependencies
feat: manage Python 3 compatiblity with dependencies
2021-04-20 15:38:29 +05:30
Rohan Bansal
524b81abd9 feat: manage Python 3 compatiblity with dependencies 2021-04-20 14:13:55 +05:30
Marica
0278646fd8 fix: Cashier query in POS Opening/Closing Entry (#25399) 2021-04-20 12:53:33 +05:30
Marica
125c3d64a9 fix: Cashier query in POS Opening/Closing Entry (#25398) 2021-04-20 12:53:22 +05:30
Marica
b91fcbd70e fix: Ignore Customer Group Perm on AlL Products page (#25396) 2021-04-19 22:21:07 +05:30
Marica
846200d069 fix: Ignore Customer Group Perm on AlL Products page (#25397) 2021-04-19 22:20:01 +05:30
Rucha Mahabal
c221682373 fix: Bulk Salary Structure Assignment (#25389) 2021-04-19 21:11:27 +05:30
Rucha Mahabal
923fb008c7 fix: remove non-standard module cards from Home Workspace (#25391) 2021-04-19 21:09:47 +05:30
Raffael Meyer
4a1159408a Merge branch 'develop' into feature/check-field-subscription-invoice 2021-04-19 16:40:35 +02:00
Meike Nedwidek
ebbcc90d89 add check field for subscription invoices if they should be submitted automatically 2021-04-19 15:28:37 +02:00
Deepesh Garg
047044f975 fix: Add amend perm for loan and system manager for loan doctypes 2021-04-19 18:27:37 +05:30
Deepesh Garg
135b852cf0 fix: Use party account currency 2021-04-19 17:27:26 +05:30
pateljannat
73896ce94c fix: conflicts 2021-04-19 16:50:39 +05:30
pateljannat
3b54b1e975 fix: report name and columns 2021-04-19 16:49:28 +05:30
Rucha Mahabal
5d7f7094d6 Merge branch 'develop' into employee-util-report 2021-04-19 16:24:55 +05:30
Hussain Nagaria
1f8326bb1f chore: Add Report to Dashboard 2021-04-19 16:19:13 +05:30
Nabin Hait
840c921229 Merge branch 'develop' into purchase-invoice-to-purchase-receipt-develop 2021-04-19 13:30:19 +05:30
Deepesh Garg
cb718fce88 feat: Role to allow over billing, delivery, receipt (#24854)
* feat: Role to allow  over billing, delivery, receipt

* fix: Typo
2021-04-19 13:25:15 +05:30
Rakshith N
ceba5774be fix(pos): special character scanning in point of sale (#25353)
Co-authored-by: rakshith.n <rakshith.n@promantia.com>
Co-authored-by: Saqib <nextchamp.saqib@gmail.com>
2021-04-19 13:21:49 +05:30
Afshan
632166a933 fix: make filters for payroll entry (#25386) 2021-04-19 12:58:27 +05:30
Ankush Menat
edf3dfa5a4 fix: commit leave_allocation change to db (#25382) (#25383) 2021-04-19 12:47:41 +05:30
Jannat Patel
119b27b97f feat: Delayed Tasks Summary (#25024)
* feat: delayed deliverables summary

* fix: sider

* fix: renamed to delayed tasks

* fix: renamed test

* fix: test

* fix: sider

* fix: dates, validations and chart

* fix: space and column width

* feat: Sort tasks by descending order of delay

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2021-04-19 12:46:14 +05:30
Alan
ac8a467b0a fix: exclude spurious Stock Entry Types from 'consumed' calculation (#25352)
* fix: exclude spurious 'Stock Entry Type's from 'consumed' calculation

* fix: filter using purpose, make requested changes

Co-authored-by: Ankush Menat <ankush@iwebnotes.com>
2021-04-19 12:38:25 +05:30
Deepesh Garg
bb746fcbe4 fix: Updated filters for process statement of accounts 2021-04-19 12:19:31 +05:30
Ankush Menat
6c88ab07c7 fix: commit leave_allocation change to db (#25382) 2021-04-19 11:51:46 +05:30
Afshan
b6d2106184 fix: available employee for selection (#25378)
* fix: available employee for selection

* fix: available employee for selection

fix: available employee for selection
2021-04-19 11:48:43 +05:30
Afshan
9c9907cf8e fix: available employee for selection (#25377)
* fix: available employee for selection

* fix: available employee for selection

fix: available employee for selection
2021-04-19 11:48:28 +05:30
Marica
e8bc912ffc perf: Fetching exchange rate on every line item slows down PO (#25345)
* fix: Dont fetch exchange rates for each line item once fetched at parent
`

* perf: Use price list conversion rate from parent

- If price list conversion rate exists in args already from earlier call, use that
- `get_price_list_currency_and_exchange_rate` wont be called for each child row

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2021-04-19 11:05:21 +05:30
Jannat Patel
dcdd3bebbe feat: Timer in LMS Quiz (#24246)
* feat: new fields in quiz doctypes

* feat: timer in lms quiz

* fix: variable initialisation

* fix: context, exception fix

* fix:sider

* fix:sider

* fix: indentation

* fix: timer

* fix: sider

* fix: return value and format

* fix: show time taken only after all attempts are over

* fix: sider

Co-authored-by: pateljannat <jannatpatel@MacBook-Air.local>
Co-authored-by: Marica <maricadsouza221197@gmail.com>
2021-04-19 10:36:40 +05:30
Ankush Menat
7eac4a250d fix: functions using mutable defaults (#25370) 2021-04-19 10:33:39 +05:30
Saqib
e782531529 fix: Apply single transaction threshold on net_total instead of supplier credit amount (#25243)
* fix: Apply single transaction threshold on net_total instead of supplier credit amount

* fix: Apply single transaction threshold on net_total instead of supplier credit amount

* fix: test

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2021-04-19 10:15:51 +05:30
Deepesh Garg
1e0d22a38f Merge pull request #24805 from alyf-de/improve_taxes_setup
refactor: Setup Taxes and Charges
2021-04-19 09:12:47 +05:30
Raffael Meyer
9ee6e4feb8 Merge branch 'develop' into improve_taxes_setup 2021-04-18 18:34:41 +02:00
barredterra
d397bb1b74 Merge branch 'improve_taxes_setup' of https://github.com/alyf-de/erpnext into improve_taxes_setup 2021-04-18 18:34:02 +02:00
barredterra
80d44cada4 fix: remove is_default from country wise tax 2021-04-18 18:33:34 +02:00
rohitwaghchaure
4ed5d994a4 Merge pull request #25374 from ankush/shipment_status_update
fix: commit  changes to shipment status in database
2021-04-18 17:56:22 +05:30
Ankush Menat
c28fcba779 ci(semgrep): add correctness rule for on_cancel
Changes done to doctype object in `on_submit` are not commited to
database. Add rule to catch similar bugs.
2021-04-18 13:22:19 +05:30
Ankush Menat
e972ceb798 fix: patch for updating shipment status 2021-04-18 13:22:19 +05:30
Ankush Menat
9229ee1745 fix: update shipment status in database
Caught by semgrep rule:
https://github.com/frappe/erpnext/blob/develop/.github/helper/semgrep_rules/frappe_correctness.yml#L4
2021-04-18 13:22:19 +05:30
rohitwaghchaure
72e3a81878 Merge pull request #25375 from ankush/minor_semgrep_fixes
fix: remove duplicate keys from dictionaries
2021-04-18 13:04:00 +05:30
Raffael Meyer
ef4c494b2b Merge branch 'develop' into improve_taxes_setup 2021-04-17 19:38:36 +02:00
barredterra
476fff149b Merge branch 'develop' into improve_taxes_setup 2021-04-17 18:41:31 +02:00
Ankush Menat
ad6a2657ae chore: minor translation fixes 2021-04-17 16:56:09 +05:30
Ankush Menat
dedf2c1b61 fix: remove duplicate keys from dictionaries 2021-04-17 16:56:08 +05:30
Saqib
75e13f7bb6 fix(e-invoicing): add company validation for e-invoicing (#25348)
Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2021-04-17 15:38:47 +05:30
Saqib
18c7815a1b fix: presentation currency in statement of accounts (#25367) 2021-04-17 15:37:40 +05:30
rohitwaghchaure
fbc0d16d8b Merge pull request #25372 from ankush/eq_assignment_fix
fix: equality check instead of assignment in cart
2021-04-17 13:43:54 +05:30
rohitwaghchaure
1254af502b Merge pull request #25362 from anupamvs/disable_rounded_total
feat: added Disable Rounded Total in sales transactions
2021-04-17 13:30:24 +05:30
Ankush Menat
d6be154ac2 fix: implicit string concatenation (#25371)
* fix: implicit string concatenations

* chore: rerun healthcare patch for company fields
2021-04-16 22:08:44 +05:30
Ankush Menat
67e647232c ci(semgrep): Add semgrep testing (#24871)
Adds semgrep testing in CI.

Refer to:
- https://github.com/frappe/frappe/pull/12524
- https://github.com/frappe/frappe/pull/12577
2021-04-16 21:44:49 +05:30
Ankush Menat
adf974810d fix: equality check instead of assignment in cart 2021-04-16 21:15:50 +05:30
Saqib
36247faf1a fix(e-invoicing): add company validation for e-invoicing (#25349)
* fix(e-invoicing): add company validation for e-invoicing

* fix: test
2021-04-16 18:45:19 +05:30
Nabin Hait
eeece59a17 Merge branch 'develop' into disable_rounded_total 2021-04-16 18:44:17 +05:30
Marica
ede339f80b fix: Serial No not updated correctly via Inter Company Stock Transfer (#25006)
* fix: Serial No not updated correctly via Inter Company Stock Transfer

* chore: Added More Test Cases for inter company Serial Transfer

* fix: Test for serial no duplication

- fixed serial no test
- made errors more meaningful on serial no validation

* fix: Stock Reco Test

Co-authored-by: Suraj Shetty <13928957+surajshetty3416@users.noreply.github.com>
2021-04-16 18:42:54 +05:30
Jannat Patel
b1aad63a99 fix: leave policy in leave allocation (#25334)
Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2021-04-16 16:08:22 +05:30
Raffael Meyer
6daae681bd Merge branch 'develop' into datev_fixes 2021-04-16 12:37:14 +02:00
Hussain Nagaria
2399e84052 Merge branch 'employee-util-report' of https://github.com/NagariaHussain/erpnext into employee-util-report 2021-04-16 15:41:25 +05:30
Hussain Nagaria
f1b4ce7430 feat: Add filtering by department
Also:

- Add department filter to js
- Add department column to report
- Fetch only those timesheets which have an Employee Linked
- Update unit tests
2021-04-16 15:36:43 +05:30
Anupam
9d9c256e70 feat: added Disable Rounded Total in sales transactions 2021-04-16 00:11:40 +05:30
Afshan
4b496b65b7 fix: filter for employees in salary slip (#25361) 2021-04-15 23:53:12 +05:30
Afshan
c0db286dc1 fix: filter for employees in salary slip (#25360) 2021-04-15 23:48:25 +05:30
Ankush Menat
799b3c26a4 Merge pull request #25359 from 18alantom/fix_shipment_pickup_to
fix: shipment pickup_to, pickup_from functionality.
2021-04-15 21:16:24 +05:30
Ankush Menat
5207edc188 Merge branch 'develop' into fix_shipment_pickup_to 2021-04-15 21:01:52 +05:30
18alantom
6179cc1311 fix: make pickup_to and pickup_from mandatory fields 2021-04-15 20:36:28 +05:30
18alantom
597bb8be18 fix: remove pickup_to, pickup_from and get_pickup_time
relies on server-side validation instead js controller
2021-04-15 20:32:45 +05:30
Rucha Mahabal
56c428663f fix: Additional Salary component amount not getting set (#25356) 2021-04-15 18:54:38 +05:30
Rucha Mahabal
39b1cd827a fix: Additional Salary component amount not getting set (#25355) 2021-04-15 18:54:29 +05:30
rohitwaghchaure
72929aab38 Merge pull request #24878 from anupamvs/planning
feat: add total available stock field in PO
2021-04-15 16:28:49 +05:30
Sun Howwrongbum
c50fbc6897 fix: list lookup with undefined variable (#25210)
Co-authored-by: Ankush Menat <ankush@iwebnotes.com>
2021-04-15 14:52:13 +05:30
rohitwaghchaure
640b5e00ce Merge pull request #25152 from ankush/customer_duplicates
fix: disable auto naming of customer during import
2021-04-15 14:46:11 +05:30
rohitwaghchaure
1bdc457777 Merge pull request #25304 from ankush/fix_sl_rounding
fix(stock_ledger): round off values near to zero
2021-04-15 14:44:09 +05:30
Saqib
593071bd53 fix: currency symbol in bank transaction list view (#25336) 2021-04-15 14:12:11 +05:30
Anupam Kumar
ee0dda6ba5 Merge branch 'develop' into planning 2021-04-15 12:48:25 +05:30
Marica
61f5f36c65 Merge pull request #24910 from AndyOverLord/patch-8
fix: copy_parent_value_in_all_row function error
2021-04-14 19:04:23 +05:30
Marica
f045fde9f4 Merge branch 'develop' into patch-8 2021-04-14 18:56:15 +05:30
Marica
24e45163d5 fix: Sider 2021-04-14 18:53:15 +05:30
Ganga Manoj
c4565651ff fix: Let Administrator delete company transactions (#25300)
Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2021-04-14 17:11:36 +05:30
Saqib
b54cc7c7f5 fix: pos print receipt (#25330) 2021-04-14 15:09:11 +05:30
Saqib
d4fd1038dc fix: pos print receipt (#25329) 2021-04-14 15:07:10 +05:30
Saqib
8798f30808 fix: pos print receipt (#25328) 2021-04-14 15:05:33 +05:30
rohitwaghchaure
ac6facda3d Merge pull request #25186 from rohitwaghchaure/fixed-incorrect-batch-selected-in-purchase-rceipt-develop
fix: incorrect batch picked in subcontracted purchase receipt
2021-04-14 14:35:12 +05:30
rohitwaghchaure
3d9d4e03de Merge pull request #25145 from rohitwaghchaure/fixed-incorrect-incoming-rate-for-sales-return-issue-develop
fix: incorrect incoming rate for the sales return
2021-04-14 14:34:46 +05:30
Nabin Hait
2535fe9b1e fix: Resolved merge conflict 2021-04-14 13:09:50 +05:30
rohitwaghchaure
3f6ba12344 Merge pull request #24408 from rohitwaghchaure/custom-user-type-feat
feat: Employee Self Service
2021-04-14 11:54:25 +05:30
Nabin Hait
1bc65ddbe4 Merge branch 'develop' into purchase-invoice-to-purchase-receipt-develop 2021-04-14 11:23:34 +05:30
Nabin Hait
90df99e470 Merge branch 'develop' into fixed-incorrect-incoming-rate-for-sales-return-issue-develop 2021-04-14 11:23:25 +05:30
Nabin Hait
5931931c93 Merge branch 'develop' into customer_duplicates 2021-04-14 11:23:12 +05:30
Nabin Hait
f7441c4c0a Merge branch 'develop' into fixed-incorrect-batch-selected-in-purchase-rceipt-develop 2021-04-14 11:23:00 +05:30
Nabin Hait
b7b35734a7 Merge branch 'develop' into employee-util-report 2021-04-14 11:22:51 +05:30
Deepesh Garg
e2dc102bc6 fix: Zero amount completed delivery notes being shown in Sales Invocie get items (#25317) 2021-04-14 11:21:11 +05:30
Deepesh Garg
b67058869a fix: Round off final tax amount instead of current tax amount (#25188)
* fix: Round off final tax amount instead of current tax amount

* fix: Syntax error

* fix: Indentation

* fix: Round Off taxes order execution

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2021-04-14 11:20:27 +05:30
Deepesh Garg
b717420842 fix: Role to override maintain same rate check in transactions (#25193)
* feat: configurable action if the same purchase/selling rate is not maintained

* fix: Role to override maintain same rate check in transactions

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2021-04-14 10:43:45 +05:30
Nabin Hait
dd02b5abf1 Merge branch 'develop' into fix_sl_rounding 2021-04-14 10:36:40 +05:30
Rohit Waghchaure
a8f78fabfd fix: patch failing while migrating from v7 to v13 2021-04-13 18:51:21 +05:30
Rohit Waghchaure
610ccd4c03 fix: modified permission 2021-04-13 18:51:21 +05:30
Rohit Waghchaure
03635fb0c4 feat: ESS User 2021-04-13 18:51:21 +05:30
Deepesh Garg
ca412d37c8 Merge pull request #25290 from deepeshgarg007/gstr_1_taxable_value_update
fix: Taxable value including Freight and Forwarding charges in GSTR-1 Report
2021-04-13 17:49:56 +05:30
Nabin Hait
10c61376e3 fix: Backport missing commits to develop branch (#25305) 2021-04-13 15:46:01 +05:30
Marica
1f9d231acf Merge branch 'develop' into patch-8 2021-04-13 15:43:46 +05:30
Deepesh Garg
2fe3056fa2 Merge pull request #24993 from frappe/ishanloya-regional
Correct state code for 'Other Territory'
2021-04-13 15:37:29 +05:30
Deepesh Garg
9aad73b9f0 Merge pull request #25195 from ankush/use_isinstance_instead_of_type
fix: broken type check in stock ageing report
2021-04-13 15:24:53 +05:30
Deepesh Garg
0dcb48a6ee Merge pull request #25167 from ankush/escape_sql_credit_report
fix: escape sql filters in credit report
2021-04-13 15:24:15 +05:30
Deepesh Garg
3db8ba2d4a Merge pull request #25033 from anupamvs/se-add-to-transit
fix: unable to submit stock entry
2021-04-13 14:59:54 +05:30
Deepesh Garg
c05f4ee1aa Merge pull request #25082 from AfshanKhan/add-blank-for-status-issue-reports
fix: added blank option for status in report related to issue
2021-04-13 14:59:01 +05:30
Deepesh Garg
bb92929048 Merge pull request #25256 from nextchamp-saqib/italy-e-invoicing
feat(italy): add document type field for e-invoicing
2021-04-13 13:48:21 +05:30
Suraj Shetty
36083ff36c Merge pull request #25310 from rmehta/grid-field-fix 2021-04-13 12:40:27 +05:30
Suraj Shetty
82d0a1a13e style: Add missing semicolons
- & make formatting consistent
2021-04-13 12:35:42 +05:30
Rushabh Mehta
ff935b4586 fix(minor): fix dynamically changing grid properties 2021-04-13 12:09:36 +05:30
Rushabh Mehta
3c58fd4d5e fix(minor): fix dynamically changing grid properties 2021-04-13 12:05:10 +05:30
Rushabh Mehta
65f25c27b3 fix(minor): fix dynamically changing grid properties 2021-04-13 11:58:16 +05:30
Abdullah Abouzekry
20140425c8 fix: sales order not saving due type mismatch in promo scheme (#24748) (#25222) 2021-04-13 11:36:39 +05:30
Deepesh Garg
1f49335335 Merge branch 'develop' into gstr_1_taxable_value_update 2021-04-13 10:29:52 +05:30
Ankush Menat
34d00772e7 Merge pull request #25303 from ankush/fix_bom_test
test: ignore floating point errors in test_bom
2021-04-12 20:34:10 +05:30
Ankush Menat
6a014d12c1 fix(stock_ledger): round off values near to zero 2021-04-12 20:21:27 +05:30
Ankush Menat
c65751d97f test: ignore floating point errors in test_bom 2021-04-12 19:45:34 +05:30
Saqib
a19c98255f fix: patch condition (#25301) 2021-04-12 19:02:28 +05:30
Saqib
9320316462 feat(india): bulk e-invoice generation (#24969) 2021-04-12 17:55:46 +05:30
Andy Zhu
bffe933c22 Fix: attempts to add overrides function
Overrides parent_fieldname in outer form to all child rows's fieldname
2021-04-12 22:49:26 +12:00
rohitwaghchaure
5e8ec48e7f Merge pull request #25294 from rohitwaghchaure/changed-scheduler-check-time
fix: update scheduler check time
2021-04-12 16:12:13 +05:30
Rohit Waghchaure
2339de7333 fix: update scheduler check tim 2021-04-12 16:09:55 +05:30
Saqib Ansari
faca478317 fix: payment amount showing in foreign currency 2021-04-12 15:40:27 +05:30
Deepesh Garg
719e0c1e60 fix: Taxxable value including Freight and Forwarding charges in GSTR-1 Report 2021-04-12 14:37:43 +05:30
Ankush Menat
53ce877ad9 Merge branch 'develop' into escape_sql_credit_report 2021-04-12 14:37:31 +05:30
Saqib
49336b8065 fix: consolidated sales invoice posting date (#25119) 2021-04-12 12:17:50 +05:30
Prssanna Desai
1fd1e0d4e9 Merge pull request #25287 from prssanna/invoice-timesheet-fix
fix: declare data before assigning
2021-04-12 12:07:29 +05:30
prssanna
42f4a00c88 fix: declare data before assigining 2021-04-12 12:01:20 +05:30
Marica
be26e59087 Merge pull request #25196 from noahjacob/UX
fix: Company field in Warehouse
2021-04-12 11:08:45 +05:30
Deepesh Garg
5f3d7f547c fix: Item wise tax rate for consolidated POS invoice (#25029)
* fix: Item wise tax rate for consolidated POS invoice

* fix: Do not alter item wise taxes for consolidated invoices

* fix: Add test case

* fix: Update

* fix: Set opening stock for test item

* fix: Add valuation rate for opening stock
2021-04-12 10:56:47 +05:30
Deepesh Garg
c36e48a869 fix: GST on freight charge in e-invoicing (#25000)
* fix: GST on freight charge in e-invocing

* fix: Add patch for taxable value field

* fix: Handle discounts on net total

* fix: Handle all types of discounts for e-invoicing

* fix: Absolute taxable values

* fix: Use correct tax amount
2021-04-12 10:55:43 +05:30
Marica
99522252c4 Merge branch 'develop' into UX 2021-04-12 10:51:24 +05:30
Anupam Kumar
9f73bd8040 fix: don't delete mode of payment account details while deleting company transactions (#25217) 2021-04-12 10:31:36 +05:30
Saqib
b8a270074e fix(pos): cannot set qty to less than zero (#25258) 2021-04-12 10:28:05 +05:30
Anoop
207166fe8b fix(patch): copy Lab Test / Template renamed field values (#25276)
reload_doc doctypes introduced since v11
2021-04-12 10:25:34 +05:30
Ankush Menat
d235fc75ad fix: remove nonexistent method from pick list (#25279)
This method is merged in calculate_rate_and_amount() during repost item
valuation refactoring.

Ref:
e10f0a5a6c (diff-a160e3a8907dcdf28ce7728bb7dd45914ad8ab033489ea3de4c80fb1c4ca7fe9)
2021-04-12 10:23:06 +05:30
Deepesh Garg
4d4d7074d0 Merge pull request #25053 from deepeshgarg007/delivery_note_gst_category
fix: Add GST category field in Delivery Note
2021-04-10 22:12:42 +05:30
Deepesh Garg
1466e2d758 Merge pull request #25271 from deepeshgarg007/loan_penalty_new_fix
fix: Consider paid repayment entries in subsequent loan repayments
2021-04-10 21:00:46 +05:30
Deepesh Garg
81ecd0b8b6 Merge branch 'develop' of https://github.com/frappe/erpnext into delivery_note_gst_category 2021-04-10 20:54:38 +05:30
Deepesh Garg
b58590251b fix: minor improvements and tests 2021-04-10 19:55:36 +05:30
rohitwaghchaure
5899477cbb Merge pull request #25015 from rohitwaghchaure/fixed-patch-item-reposting-for-incorrect-sl-and-gl-develop
fix: patch
2021-04-10 18:58:44 +05:30
Raffael Meyer
dc9ef51d97 Merge branch 'develop' into improve_taxes_setup 2021-04-10 15:09:41 +02:00
Deepesh Garg
f38a653a08 fix: Show exact error message in datetime 2021-04-10 18:34:51 +05:30
Deepesh Garg
e7efbc1d33 Merge branch 'develop' of https://github.com/frappe/erpnext into loan_penalty_new_fix 2021-04-10 18:33:38 +05:30
Deepesh Garg
37d6c19a34 fix: Consider paid repayment entries in subsequent loan repayments 2021-04-10 18:33:26 +05:30
Deepesh Garg
8a01dbe8e1 Merge pull request #25261 from ankush/issue_status_banner_fix
fix: condition for SLA status banner
2021-04-10 17:56:51 +05:30
Rohit Waghchaure
a5d062453e feat: added test case 2021-04-10 10:49:31 +05:30
Rohit Waghchaure
cb6494876f feat: purchase receipt creation from purchase invoice 2021-04-10 10:49:30 +05:30
Rohit Waghchaure
1db8c51749 fix: changed logic 2021-04-10 10:45:29 +05:30
Rohit Waghchaure
b9aa775f3b fix: pricing_rule test cases 2021-04-10 10:45:28 +05:30
Rohit Waghchaure
1358443cdb fix: patch 2021-04-10 10:42:08 +05:30
Deepesh Garg
c85c243f9c Merge pull request #25255 from nextchamp-saqib/issue-condition-fix
fix: condition for setting agreement status
2021-04-09 21:40:14 +05:30
Deepesh Garg
df9388aa8e Merge pull request #25086 from deepeshgarg007/advance_amount_precision
fix: Precision issues while allocating advance amount
2021-04-09 21:39:02 +05:30
noahjacob
110f28f869 Company field editable and is readonly after saving. 2021-04-09 20:01:47 +05:30
Saqib
14b98c1737 Merge branch 'develop' into issue-condition-fix 2021-04-09 18:29:01 +05:30
Anupam Kumar
986452107b fix: Lead Source's module (#24583)
* fix: Lead Source's module

* fix: patch fix
2021-04-09 18:15:51 +05:30
Anupam Kumar
a91d7bd4b5 Merge branch 'develop' into se-add-to-transit 2021-04-09 18:00:03 +05:30
Anupam Kumar
cd2aedd0c6 Merge branch 'develop' into planning 2021-04-09 17:59:47 +05:30
Ankush Menat
5451bbf7d2 fix: condition for SLA status banner
If the document is NOT in the closed state and fulfilled then there
won't be any banner. This bug was introduced while fixing a bug related
to buttons, so separated out code for showing buttons and showing
banners.
2021-04-09 17:19:02 +05:30
rohitwaghchaure
526f76c27d Merge pull request #25257 from rohitwaghchaure/travis-fix-for-project
fix: travis
2021-04-09 17:07:22 +05:30
Rohit Waghchaure
ca5e10892c fix: travis 2021-04-09 16:23:45 +05:30
Afshan
dc73a9995d Merge branch 'develop' into add-blank-for-status-issue-reports 2021-04-09 13:04:34 +05:30
Marica
c6b3766fb2 Merge pull request #24921 from Anurag810/item-dashboard-fixes
fix: precision and formatted document for stock level in item dashboard.
2021-04-09 12:43:06 +05:30
Saqib Ansari
032246dc2b feat(italy): add document type field for e-invoicing 2021-04-09 12:08:24 +05:30
Marica
d38618fc34 Merge branch 'develop' into item-dashboard-fixes 2021-04-09 11:57:56 +05:30
Marica
5467d7c3e3 fix: Use system precision instead of SLE precision 2021-04-09 11:56:49 +05:30
Marica
a7ac01153e fix: Remove redundant import and import cint 2021-04-09 11:55:44 +05:30
Marica
ad75944960 Merge pull request #25105 from Anuja-pawar/fix_picked_qty_in_DN
fix: Picked Qty conversion from Stock Qty to Qty while creating DN from Pick List
2021-04-09 11:48:56 +05:30
Saqib Ansari
e7813b69c4 fix: condition for setting agreement status 2021-04-09 11:46:16 +05:30
Marica
b89a40aa3c Merge branch 'develop' into fix_picked_qty_in_DN 2021-04-09 11:45:39 +05:30
Marica
7f0e92c9b9 Merge pull request #25232 from nextchamp-saqib/coa-importer-validate-fix
fix: keyerror while validating coa file
2021-04-09 11:44:40 +05:30
Deepesh Garg
63e6036d12 Merge pull request #25235 from ankush/remove_purch_inv_validation
fix: remove gst name validation for purchase Invoice
2021-04-09 10:48:34 +05:30
barredterra
e66cf0aa44 fix: hanging indent 2021-04-08 18:26:45 +02:00
barredterra
0a45fc8c58 fix: remove unused import 2021-04-08 18:25:17 +02:00
barredterra
3a12f1f1ae fix: prettier error log 2021-04-08 17:53:48 +02:00
Saqib
4191e7999d chore: add error title
Co-authored-by: Marica <maricadsouza221197@gmail.com>
2021-04-08 21:04:56 +05:30
barredterra
ea0fd31f60 Merge branch 'datev_fixes' of https://github.com/alyf-de/erpnext into datev_fixes 2021-04-08 17:25:54 +02:00
Raffael Meyer
3b4b17476a Merge branch 'develop' into datev_fixes 2021-04-08 17:25:12 +02:00
Deepesh Garg
edb4663258 Merge pull request #25251 from nextchamp-saqib/einv-ack-no-fix
fix(india): set correct ack no. on irn generation
2021-04-08 20:48:01 +05:30
barredterra
c6e13ac218 fix: patch to fill Debtor/Creditor Number 2021-04-08 16:57:55 +02:00
barredterra
ed36fb2073 docs: doctring for patch 2021-04-08 16:57:20 +02:00
barredterra
03425071e7 fix: patch to add custom fields 2021-04-08 16:31:00 +02:00
barredterra
368a6541e9 fix: Debtor/Creditor Number is not translatable 2021-04-08 16:26:56 +02:00
Saqib Ansari
30720d2139 fix: set correct ack no. on irn generation 2021-04-08 19:06:44 +05:30
Rucha Mahabal
b7aa658a51 refactor(HR): Add missing reports and doctypes to the Workspace (#24994)
* refactor(HR): Add missing reports and doctypes to the Workspace

* refactor: remove Employee Tax and Benefits from HR Workspace

Co-authored-by: Anurag Mishra <32095923+Anurag810@users.noreply.github.com>
2021-04-08 18:13:21 +05:30
Jannat Patel
d9fa79de99 fix: serial no refresh issue (#25127)
* fix: serial no refresh issue

* fix: sider
2021-04-08 16:04:57 +05:30
Anupam Kumar
9d830255c1 Merge branch 'develop' into se-add-to-transit 2021-04-08 14:44:08 +05:30
rohitwaghchaure
f9fde054e1 Merge pull request #25242 from rohitwaghchaure/fixed-test-case-for-bom-cost
fix: bom cost test case
2021-04-08 14:39:08 +05:30
Marica
6a98d39201 Merge branch 'develop' into fixed-incorrect-batch-selected-in-purchase-rceipt-develop 2021-04-08 13:57:35 +05:30
HENRY Florian
e286750a0f fix: UOM length unit in global setup list is empty (#24855)
* When ERPNext is installed in localized language the category of UOM Conversion Factor is tranlasted into installed languaes. Filter must be locallized

* fix

* fix

Co-authored-by: Marica <maricadsouza221197@gmail.com>
2021-04-08 13:56:29 +05:30
Marica
fb9fc944c5 Merge branch 'develop' into coa-importer-validate-fix 2021-04-08 13:46:42 +05:30
Rohit Waghchaure
fa8bb87a86 fix: bom cost test case 2021-04-08 13:38:22 +05:30
rohitwaghchaure
5d3f665cc5 Merge pull request #25240 from ankush/job_card_rounding
fix: round total quantity in job card
2021-04-08 13:10:09 +05:30
Ankush Menat
cb625d868c fix: round total quantity in job card 2021-04-08 12:05:52 +05:30
Saqib
f10d107a0a Merge branch 'develop' into coa-importer-validate-fix 2021-04-08 11:25:29 +05:30
Anupam Kumar
dfdf72cbb2 Merge branch 'develop' into planning 2021-04-08 10:58:05 +05:30
Anupam Kumar
8edf9d23c0 Merge branch 'develop' into se-add-to-transit 2021-04-08 10:57:50 +05:30
barredterra
94f293940c fix: better party export 2021-04-07 20:06:16 +02:00
barredterra
4fe2d35b2e feat: more infos for transactions 2021-04-07 20:05:41 +02:00
barredterra
b39608a02e fix: handle encoding errors
replace unknown characters by '?'
2021-04-07 20:04:38 +02:00
barredterra
6b2e4f2b5d feat: add custom field debtor_creditor_number to Party Account 2021-04-07 20:03:59 +02:00
barredterra
09c7598a67 fix: make account field non-mandatory 2021-04-07 20:03:33 +02:00
Ankush Menat
76c8521010 fix: remove gst name validation for purch Invoice 2021-04-07 16:28:13 +05:30
Afshan
e2da3cbc28 fix: payroll issues (#24540)
* fix: payroll issues

* fix: enhancements

* fix: rename variables and refactor

* fix: slider

* fix: added missing arguments

* fix: test cases

* fix: slider

* fix: slider

fix: slider

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2021-04-07 15:13:44 +05:30
Saqib Ansari
5541aeaa82 fix: keyerror while validating coa file 2021-04-07 12:34:20 +05:30
Walstan Baptista
90e240c3e6 fix: frappe.whitelist for doc methods (#25230) 2021-04-07 11:32:51 +05:30
Deepesh Garg
3d5a4ffd66 Merge pull request #24879 from deepeshgarg007/loan_fixes_phase_2
fix: Loan Repayment entry cancellation on salary slip cancel
2021-04-07 10:33:46 +05:30
Deepesh Garg
5af6aea9f9 fix: Posting Date check 2021-04-07 09:46:13 +05:30
Deepesh Garg
d551940dc5 fix: Remove comments 2021-04-06 23:55:48 +05:30
Deepesh Garg
a42194f3d5 Merge branch 'develop' of https://github.com/frappe/erpnext into loan_fixes_phase_2 2021-04-06 23:53:34 +05:30
Rucha Mahabal
d77ea7c88b Merge pull request #25190 from ruchamahabal/approver-perms
feat(HR): share doc with employee approvers if they don't have access
2021-04-06 14:32:34 +05:30
Rucha Mahabal
0bcd3c45ed fix: leave approver perms test 2021-04-06 13:46:53 +05:30
Hussain Nagaria
d2da7b673b fix: Sider Issues 2021-04-06 11:44:54 +05:30
Hussain Nagaria
33e0c8ed19 test: Unique Employee IDs for tests 2021-04-06 11:40:35 +05:30
Deepesh Garg
dfe91b5df3 Merge pull request #25212 from deepeshgarg007/loan_shortfall_preference
fix: Give first preference to loan security on repayment
2021-04-06 11:06:03 +05:30
Anupam Kumar
7b6c8bb3ab fix: error message compensatory leave request (#25206) 2021-04-06 10:20:10 +05:30
Rucha Mahabal
d1970d3c38 Merge branch 'develop' into approver-perms 2021-04-06 10:09:18 +05:30
Rucha Mahabal
084e90e5d3 fix(test): set user as Administrator 2021-04-06 10:07:50 +05:30
Deepesh Garg
015fd681ec fix: Give first preference to loan security on repayment 2021-04-06 00:49:46 +05:30
Hussain Nagaria
bb32f5a92a fix: Rename utilisation to utilization 2021-04-05 19:32:10 +05:30
Sagar Vora
c9cdf74dc5 test: remove print() (#25205) 2021-04-05 16:38:10 +05:30
Marica
4440ff7a0d Merge branch 'develop' into item-dashboard-fixes 2021-04-05 16:25:57 +05:30
Marica
bc50193702 Merge branch 'develop' into fix_picked_qty_in_DN 2021-04-05 16:24:53 +05:30
Sagar Vora
9967a7ce02 test: clear all existing quotations to avoid AssertionError (#25202) 2021-04-05 15:35:52 +05:30
Rucha Mahabal
9948525dd3 Merge branch 'develop' into approver-perms 2021-04-05 14:54:11 +05:30
Sagar Vora
9a0907131a test: create tax rule if it doesnt exist (#25199) 2021-04-05 14:50:09 +05:30
Walstan Baptista
8789ef16a1 test: uses _Test Item instead of _Test Item Home Desktop 100 (#25198) 2021-04-05 13:18:03 +05:30
Hussain Nagaria
ccb15de1c9 fix: Handle overtime edge case 2021-04-05 11:23:06 +05:30
Anoop
b27441b40c fix: failing patch - reload_doc new doctypes added in v13 (#25194) 2021-04-05 10:41:28 +05:30
Ankush Menat
36ff0748bf fix: broken type check in stock ageing report 2021-04-05 10:18:44 +05:30
Rucha Mahabal
b7436a04c3 fix: Ignore Permission for Leave Ledger Entry (#25172) 2021-04-04 20:09:00 +05:30
Rucha Mahabal
57ab3a5a88 Merge branch 'develop' into approver-perms 2021-04-04 19:57:58 +05:30
Rucha Mahabal
19c3286b06 fix: linter and sider issues 2021-04-04 19:54:00 +05:30
Rucha Mahabal
8c055b5469 fix: ignore share permission while sharing doc with approver 2021-04-04 18:45:06 +05:30
Rucha Mahabal
13c0a350af test: leave, expense, shift request approver permissions 2021-04-04 18:37:46 +05:30
Rucha Mahabal
ba10ef4403 feat(HR): share doc with employee approvers if they don't have access 2021-04-04 17:16:48 +05:30
Rohit Waghchaure
8b829711fc fix: incorrect batch picked in subcontracted purchase receipt 2021-04-04 12:43:38 +05:30
Sagar Vora
8aacd341c7 test: disable shopping cart before running Tax Rule tests (#25183) 2021-04-03 23:01:16 +05:30
Sagar Vora
993cf8c2cd test: cleanup BOM in test_routing and prevent overlap in test_job_card (#25180) 2021-04-03 20:25:19 +05:30
Walstan Baptista
37b826b988 fix: correct calculation for discount amount when margin is set (#25179) 2021-04-03 19:48:46 +05:30
Sagar Vora
cce3efe0c1 test: specify warehouse list to avoid error (#25174)
* test: specify warehouse list to avoid error

* test: get_all_warehouses of BOM company
2021-04-03 19:46:44 +05:30
Walstan Baptista
b7481633b1 test: adds role after setting user to Administrator (#25177) 2021-04-03 17:37:59 +05:30
Sagar Vora
f68f41d7a7 test: fix multiple tests in Leave Application (#25173) 2021-04-03 17:34:57 +05:30
Deepesh Garg
232c127295 Merge pull request #25107 from deepeshgarg007/stock_entry_serial_batch_selector
fix: Hide serial and batch selector in Stock Entry
2021-04-03 17:15:22 +05:30
Deepesh Garg
b7e7eeaf8d Merge pull request #25138 from deepeshgarg007/loan_shortfall_percentage
fix: Add shortfall ratio in Loan Security Shortfall
2021-04-03 17:13:27 +05:30
rohitwaghchaure
fe72e17a7b Merge pull request #25109 from ankush/po_to_pr_fixes
fix: incorrect status creating PR from PO after creating PI
2021-04-03 17:11:14 +05:30
Sagar Vora
f6b1fa0a1c test: clear tax rules before making POS Invoices (#25171) 2021-04-03 16:06:41 +05:30
Walstan Baptista
5d77f10baa test: docs are not deleted in tearDown (#25123)
* test: docs are not deleted in tearDown
2021-04-03 13:38:55 +05:30
Ankush Menat
87b2a51322 fix: escape sql filters in credit report
closes #24965
2021-04-03 12:34:34 +05:30
Saqib
a30d70e490 Merge branch 'develop' into customer_duplicates 2021-04-03 12:22:22 +05:30
Kaviya Periyasamy
2cef23d4c9 fix: object referencing the same address issue (#25159)
* fix: variable reference to same address

* fix: object referencing same address issue

* fix: value error
2021-04-03 11:30:49 +05:30
Hussain Nagaria
40abd2a2e1 test: Add test case for summary data 2021-04-02 19:55:54 +05:30
Hussain Nagaria
d27fc93edd feat: Add additional stats to report summary 2021-04-02 19:54:58 +05:30
Rucha Mahabal
2453b0cf6a fix: component amount calculation based on formula with abbr not working (#25117) 2021-04-02 17:00:28 +05:30
bhavesh95863
7535341016 fix(regional): remove shipping address GSTIN validation for e-invoice (#25153) 2021-04-02 15:04:48 +05:30
Ankush Menat
e41d48c7de fix: disable auto naming of customer during import 2021-04-02 14:22:04 +05:30
Marica
7f9fedf08a Merge branch 'develop' into fix_picked_qty_in_DN 2021-04-02 13:19:19 +05:30
Saqib
5447b250fe fix: place of supply of e-invoicing (#25148) 2021-04-02 12:16:19 +05:30
Deepesh Garg
7f10044195 fix: Typo 2021-04-02 12:04:42 +05:30
Jannat Patel
0353b0f5f6 Merge branch 'develop' into profitability-report 2021-04-02 10:15:28 +05:30
Rohit Waghchaure
9896907565 fix: incorrect incoming rate for the sales return 2021-04-02 00:27:08 +05:30
Afshan
ace4ce64a0 fix: validation msg for TransDocNo e-invoicing (#25121) 2021-04-01 20:28:12 +05:30
Suraj Shetty
7b97d49a58 Merge pull request #25141 from surajshetty3416/fix-get_route_options_for_new_doc
fix: get_route_options_for_new_doc for Project
2021-04-01 19:58:01 +05:30
Suraj Shetty
67169ba2d3 fix: get_route_options_for_new_doc for project 2021-04-01 19:52:07 +05:30
Marica
f46fbcc1ad Merge pull request #25118 from marination/qc-back-update
fix: Query values incorrectly escaped while back updating Quality Inspection
2021-04-01 18:30:58 +05:30
Sagar Vora
d3ee8c7731 fix: customer creation from shopping cart (#25136) 2021-04-01 18:18:19 +05:30
Deepesh Garg
eea20f83ab fix: Add shortfall ratio in Loan Security Shortfall 2021-04-01 18:13:54 +05:30
Marica
913e7254cb Merge branch 'develop' into qc-back-update 2021-04-01 17:40:46 +05:30
Walstan Baptista
446a6df662 test: set opening stock to fix NegativeStock errors (#25101)
Co-authored-by: Sagar Vora <sagar@resilient.tech>
2021-04-01 16:54:26 +05:30
Sagar Vora
88f5c42b09 test: set formula in scorecard to avoid ValidationError (#25116) 2021-04-01 16:44:05 +05:30
Anuja P
7982688508 fix: sider changes 2021-04-01 16:04:28 +05:30
Walstan Baptista
58625674f4 test: correct naming series to avoid ValidationError (#25132) 2021-04-01 15:55:37 +05:30
Marica
9ef323fcfd Merge branch 'develop' into qc-back-update 2021-04-01 15:44:20 +05:30
Anuja P
45d0b9bce6 test: added tests for Pick List for item with multiple UOM 2021-04-01 15:38:13 +05:30
Sagar Vora
4c31fbb687 fix(India): create property setters for shorter naming series (as per GST Rules) (#25128) 2021-04-01 15:32:37 +05:30
Rucha Mahabal
53a1aaf33d fix: Salary Structure object has no attribute set_totals (#25113) 2021-04-01 14:40:15 +05:30
marination
561fa6b530 fix: Don't string format args as they may not be escaped properly
- Append even conditional args to args list and send to query executer
- It will escape all values that are sent to it
- String formatting without escaping causes issues with % sign, etc.
2021-04-01 12:56:05 +05:30
Ankush Menat
1bdf9c4161 fix: patch for purchase receipt status 2021-04-01 11:58:34 +05:30
Ankush Menat
427a98d6cd fix: do not copy percent billed from PO to PR 2021-04-01 11:51:31 +05:30
Ankush Menat
8993ccb7d2 fix: update PR status in database 2021-04-01 11:51:31 +05:30
Ankush Menat
4198cf58e5 test: add tests for PO->PI, PO->PR workflow
Add failing test cases for PR status and PR percent billed.
2021-04-01 11:51:30 +05:30
Hussain Nagaria
1e772bb9a4 test: Basic report data testing 2021-04-01 00:44:35 +05:30
rohitwaghchaure
56bd4d71a9 Merge pull request #25112 from rohitwaghchaure/fixed-clear-source-warehouse
fix: not able to save material request
2021-03-31 23:58:44 +05:30
Rohit Waghchaure
825850a58f fix: not able to save material request 2021-03-31 23:55:06 +05:30
Marica
b4913e7db4 Merge pull request #23509 from AndyOverLord/patch-7
fix: Update Bin via Update Item on Purchase/Sales Order
2021-03-31 22:28:14 +05:30
Marica
bfc2590e3b Merge branch 'develop' into patch-7 2021-03-31 22:23:23 +05:30
Prssanna Desai
f3c34aa6ae fix: don't set "Company:company:default_currency" as default for currency link fields (#25095)
* fix: don't set Company:company:default_currency as default for currency link fields

* fix: Company:company:default_currency and refactor

Co-authored-by: Afshan <33727827+AfshanKhan@users.noreply.github.com>
Co-authored-by: Afshan <afshan13k@gmail.com>
2021-03-31 21:52:48 +05:30
marination
7665a85039 fix: Run Patches to updated Reserved, Requested and Ordered Qty 2021-03-31 21:03:55 +05:30
Marica
7d3eda47b4 Merge pull request #25063 from ankush/mr_stopped_validation
fix: do not fetch stopped MR in production plan
2021-03-31 20:10:54 +05:30
Deepesh Garg
9f7bb14ea1 fix: Remove console 2021-03-31 20:01:00 +05:30
Anuja P
a1d0932093 fix: suggested changes 2021-03-31 19:59:28 +05:30
Deepesh Garg
2d86eb3ab1 fix: Hide serial and batch selector in Stock Entry 2021-03-31 19:57:50 +05:30
Ankush Menat
777745f1e0 fix: do not fetch stopped MR in production plan
- Ignore stopped MR while using fetch button
- Add filter on field inside child table.

Related issue: ISS-20-21-10757
2021-03-31 19:53:19 +05:30
Anupam Kumar
1033cf72f6 fix: added flag for dont_fetch_price_list_rate in transaction (#25041) 2021-03-31 19:39:45 +05:30
Anuja P
fb9ce3f37b fix: Picked Qty conversion from Stock Qty to item Qty in DN 2021-03-31 19:26:42 +05:30
Sagar Vora
27f48739d4 test: pass force parameter to avoid LinkExistsError (#25100) 2021-03-31 18:49:03 +05:30
Sagar Vora
4e07695a08 test: use insert instead of save (#25045)
* test: use insert instead of save

* test: use do_not_save
2021-03-31 18:33:27 +05:30
Jannat Patel
11e9ae3841 fix: delivery note print error (#25080) 2021-03-31 16:24:08 +05:30
Prssanna Desai
45eccfafc1 fix: do not set standard link in Sales Invoice as custom (#25096) 2021-03-31 16:16:00 +05:30
Marica
116ac3cde7 Merge pull request #24863 from marination/drop-shipping
fix: PO not created against all selected suppliers (drop shipping)
2021-03-31 16:06:44 +05:30
Deepesh Garg
21a3ea462a fix: Purchase from registered composition dealer (#25040)
* fix: Purchase from registered composition dealer

* fix: Test case for GSTR 3b report
2021-03-31 16:05:12 +05:30
Marica
1b8d36634f Merge branch 'develop' into patch-7 2021-03-31 16:04:24 +05:30
Marica
8339987cf1 Merge branch 'develop' into drop-shipping 2021-03-31 16:03:14 +05:30
rohitwaghchaure
e353c84aa5 Merge pull request #25092 from rohitwaghchaure/fixed-multiply-issue-material-request-develop
fix: can't multiply sequence by non-int of type 'float'
2021-03-31 15:31:50 +05:30
Rohit Waghchaure
1bc53a32bf fix: can't multiply sequence by non-int of type 'float' 2021-03-31 15:30:42 +05:30
Rohan
99a8cb7143 fix: commit individual SLE rename for large datasets (#25084) 2021-03-31 15:22:00 +05:30
Marica
0af1aedf34 Merge branch 'develop' into drop-shipping 2021-03-31 15:05:11 +05:30
Saqib
0586b7db79 feat: discount configuration on early payments (#24586)
Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2021-03-31 15:03:53 +05:30
Deepesh Garg
5d73d8281b fix: Remove unintentionally added field 2021-03-31 14:10:56 +05:30
Deepesh Garg
f54d596ae1 fix: Precision issues while allocating advance amoount 2021-03-31 14:06:02 +05:30
Afshan
b07de03ddb fix: added blank option for status in report related to issue 2021-03-31 13:39:04 +05:30
Hussain Nagaria
39b75c63ad feat: Add chart generation 2021-03-31 13:13:25 +05:30
Marica
5a601ce851 Merge branch 'develop' into drop-shipping 2021-03-31 13:12:13 +05:30
Walstan Baptista
d6360755b9 chore: frappe.whitelist for doc methods (#25068)
* chore: frappe.whitelist for doc methods

* fix: incorrect spelling

* fix: sider issue

Co-authored-by: Sagar Vora <sagar@resilient.tech>
2021-03-31 12:30:32 +05:30
Marica
14c44e5e9e Merge branch 'develop' into drop-shipping 2021-03-31 12:27:32 +05:30
marination
120da991d0 fix: Test
- Preserve order of supplier list while removing duplicates
- Dont use list of set, but list of dict with unique keys
2021-03-31 12:27:57 +05:30
Hussain Nagaria
92c768972f fix: Missing quotation marks in SQL query 2021-03-31 12:26:37 +05:30
Hussain Nagaria
f5576d67dd feat: Add Report Summary generation 2021-03-31 12:25:36 +05:30
Walstan Baptista
353aa59c42 test: sets company while making a project (#25061) 2021-03-31 12:16:54 +05:30
Walstan Baptista
d65458d534 test: corrected item name (#25075) 2021-03-31 12:14:41 +05:30
Marica
8451da7924 Merge branch 'develop' into drop-shipping 2021-03-31 11:44:07 +05:30
Anurag Mishra
720f69caaf fix: column width in Recruitment analytics report (#25003)
Co-authored-by: Afshan <33727827+AfshanKhan@users.noreply.github.com>
2021-03-31 11:23:34 +05:30
marination
0673f558c1 fix: Cleaned up and fixed validation and bin updation on deletion
- Created separate smaller functions for validation and bin updation of deleted row
- Made sure previous doc (linked doc) was also updated after deletion of row
- Tests to check bin updation on add/update/delete
- Made reserved qty for subcontrating read only in bin
2021-03-31 01:42:18 +05:30
Hussain Nagaria
1a0229eb36 feat: Add report table data generation 2021-03-30 18:20:22 +05:30
Marica
c5739957de Merge branch 'develop' into patch-7 2021-03-30 18:07:32 +05:30
Anurag Mishra
679177f9e0 Merge pull request #25022 from shariquerik/employee-profile-pic-access-fix
fix: Employee profile pic upload access for erpnext user
2021-03-30 14:32:21 +05:30
Hussain Nagaria
2b85a81a1c feat: Add filters to front end 2021-03-30 13:57:44 +05:30
Rucha Mahabal
30f67c3f57 fix: add filters to account link fields in Non Profit Settings (#25060)
- fetch memberships ordered by date in certificate
2021-03-30 12:39:56 +05:30
Hussain Nagaria
b7f2ba1556 feat: Add Report boilerplate 2021-03-30 12:19:16 +05:30
Deepesh Garg
f954ec7c78 fix: Add patch for GST category field in Delivery Note 2021-03-29 20:31:11 +05:30
Sagar Vora
ba76f87e44 fix(Italy): setup, validations, optimisations (#25054)
* fix(Italy): setup, validations, optimisations

* fix: remove unused import
2021-03-29 20:18:45 +05:30
Deepesh Garg
29997414ad fix: Add GST category field in Dellivery Note 2021-03-29 19:49:52 +05:30
Sagar Vora
5c907fa7f0 test: make Stock Entry to avoid NegativeStockError (#25044) 2021-03-27 20:30:26 +05:30
Walstan Baptista
ee822a9dcd test: use different product attribute value; cleanup (#25043)
Co-authored-by: Sagar Vora <sagar@resilient.tech>
2021-03-27 19:42:25 +05:30
Raffael Meyer
1bbc8008eb Merge branch 'develop' into improve_taxes_setup 2021-03-27 15:02:58 +01:00
Walstan Baptista
d6c7d8e631 test: reset session user if test errors in test_sle (#25042) 2021-03-27 18:30:07 +05:30
Sagar Vora
868c0bf45b perf: reduce no of queries for checking if future sl entry exists (#24881) 2021-03-27 16:10:20 +05:30
walstanb
ab673d9e4b fix: minor changes 2021-03-27 12:54:49 +05:30
walstanb
225c64a1ad test: sets is_purchase_item while item creation 2021-03-27 12:54:49 +05:30
walstanb
52403c537b fix: check if gst account exists before appending 2021-03-27 12:54:49 +05:30
walstanb
9826ac4602 test: reset session user if test errors 2021-03-27 12:54:49 +05:30
walstanb
98dcf8a1fd fix: type casting for None type value 2021-03-27 12:54:49 +05:30
Anupam
096da429ed fix: unable to submit stock entry 2021-03-27 00:45:31 +05:30
rohitwaghchaure
d5759bab11 Merge pull request #24922 from rohitwaghchaure/feat-recursice-pricing-rule
feat: recursive pricing rule
2021-03-26 19:10:10 +05:30
rohitwaghchaure
86628ea287 Merge pull request #25025 from ruchamahabal/production-raw-material-enhancements
feat(Production Plan): Enhancements in Material Request Plan Item
2021-03-26 18:59:23 +05:30
Rucha Mahabal
87a70fe8cb feat: Show Required Qty as per BOM in Material Request Items 2021-03-26 18:37:50 +05:30
Rucha Mahabal
9dbabb92df feat: Add more fields to raw material download 2021-03-26 18:37:40 +05:30
Rucha Mahabal
07409990a0 fix: Ordered and Reserved Qty for Production not getting fetched in Items 2021-03-26 18:37:24 +05:30
Rucha Mahabal
1f86471656 feat: show ordered and reserved qty in Material Request Plan Item table 2021-03-26 18:36:52 +05:30
Rucha Mahabal
66bae19c16 feat(Production Plan): Consider Safety Stock in Required Qty Calculation 2021-03-26 18:36:33 +05:30
shariquerik
82d7986a2f fix: sider fix 2021-03-26 17:02:37 +05:30
shariquerik
1989375be4 fix: Employee profile pic upload access for erpnext user 2021-03-26 16:34:22 +05:30
Prssanna Desai
1bbd5c98d3 Merge pull request #24996 from prssanna/help-links-fix 2021-03-26 16:04:25 +05:30
Prssanna Desai
3da2df55f4 Merge branch 'develop' into help-links-fix 2021-03-26 15:35:17 +05:30
Sagar Vora
0b569b3e43 fix: allow creating stock entry based on work order for customer provided items (#24885) 2021-03-26 14:40:15 +05:30
prssanna
dd2a315d06 style: fix formatting 2021-03-26 14:35:47 +05:30
Marica
ffb4e3f280 Merge pull request #24937 from ankush/hide_alt_field
fix: hide alt tag if item is not shown in website
2021-03-25 20:14:52 +05:30
Anurag Mishra
344c14c9ca Merge pull request #25004 from ruchamahabal/fix-exchange-rate-in-salary-slip
fix(Payroll): Exchange Rate not getting set in Salary Slip
2021-03-25 18:12:11 +05:30
Deepesh Garg
74200bcd62 Merge pull request #24975 from frappe/revert-24039-fixed-incorrect-gstr-report-issue
Revert "fix: GSTR B2C report"
2021-03-25 16:50:10 +05:30
Deepesh Garg
7b8742bd70 Merge pull request #24998 from frappe/revert-24318-fix-currency-validation-for-party
Revert "fix: validating party currency with doc currency"
2021-03-25 16:49:50 +05:30
Rucha Mahabal
b2b12f303e fix(Payroll): Exchange Rate not getting set in Salary Slip 2021-03-25 14:48:08 +05:30
pateljannat
c0b4eea415 fix: sider 2021-03-25 14:39:05 +05:30
pateljannat
6597bf7dd7 feat: profitability report default working hours and tests 2021-03-25 13:31:43 +05:30
Mohammad Hasnain Mohsin Rajan
52701dcbbc fix: patch regional fields for old companies (#24988) 2021-03-25 12:56:33 +05:30
Marica
36d125a720 Merge branch 'develop' into item-dashboard-fixes 2021-03-25 12:32:47 +05:30
Marica
7c6f72fd39 Merge branch 'develop' into hide_alt_field 2021-03-25 12:15:58 +05:30
Syed Mujeer Hashmi
f8b44e05c4 refactor: Add student mobile number to student attendance (#24990)
To setup SMS alert notification for student attendance we need student mobile
number in this doctype.

Signed-off-by: Syed Mujeer Hashmi <mujeerhashmi@4csolutions.in>
2021-03-25 11:48:29 +05:30
Anupam Kumar
b4e842e25e fix: opportunity-quotation mapping order status (#25001) 2021-03-25 11:45:57 +05:30
Deepesh Garg
1a6e6320cf Revert "fix: validating party currency with doc currency (#24318)"
This reverts commit 02142c41bb.
2021-03-24 21:26:04 +05:30
Prssanna Desai
8a87ffc8f6 fix: POS print receipt (#24924)
* fix: POS print receipt

* fix: print recepit dialog
2021-03-24 19:52:39 +05:30
Saqib
dd39a6b47c fix(pos): mode of payments disappear on loading draft pos invoice (#24917) 2021-03-24 17:56:24 +05:30
prssanna
194dd12882 fix: re-execute add_standard_navbar_items patch
- check that same items aren't appended again
2021-03-24 16:45:32 +05:30
prssanna
97aab3ac21 fix: missing help links in navbar help dropdown 2021-03-24 16:44:49 +05:30
Anurag Mishra
4217a4b1ff Merge branch 'develop' into item-dashboard-fixes 2021-03-24 15:35:33 +05:30
Anupam Kumar
d1bbb4c311 Merge branch 'develop' into planning 2021-03-24 15:12:04 +05:30
Ishan Loya
de774ae080 Correct state code for 'Other Territory'
Corrects state code for 'Other Territory' to match e-invoicing state codes list. Attempts to fix #24992
2021-03-24 12:30:51 +05:30
rohitwaghchaure
575f8f226b fix: repost not completed backdated transactions (#24980) 2021-03-24 11:30:53 +05:30
Deepesh Garg
734f5c2533 Merge pull request #24971 from deepeshgarg007/loan_security_shortfall_process_update
fix: Pending shortfall update  on processing loan security shortfall
2021-03-24 11:24:49 +05:30
Anupam Kumar
5ce0569f80 fix: validate_series (#24984) 2021-03-23 21:13:41 +05:30
Deepesh Garg
82983369fa fix: Period list for exponential smoothing forecasting report (#24982) 2021-03-23 21:11:01 +05:30
Jannat Patel
12f0923a61 fix: serial no trim issue (#24949)
* fix: serial no trim issue

* fix: valid serial nos

* fix: sider

Co-authored-by: Marica <maricadsouza221197@gmail.com>
2021-03-23 21:09:49 +05:30
Afshan
02142c41bb fix: validating party currency with doc currency (#24318)
* fix: validating supplier currency

* fix: compare current currency with company currency as well.

* fix: replaced or with add in condition

* fix: conditioning to get proper payment terms values

Co-authored-by: Saqib <nextchamp.saqib@gmail.com>
2021-03-23 20:53:56 +05:30
Syed Mujeer Hashmi
f114da2f67 refactor: Make Discharge Schedule Date as Datetime (#24940)
* refactor: Make Discharge Schedule Date as Datetime

Like Admitted Datetime make discharge date as discharge datetime.

Signed-off-by: Syed Mujeer Hashmi <mujeerhashmi@4csolutions.in>

* fix: Add patch for renaming discharge_date to discharge_datetime

Signed-off-by: Syed Mujeer Hashmi <mujeerhashmi@4csolutions.in>

* fix: quote style

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2021-03-23 17:48:25 +05:30
Marica
23b32381e7 Merge pull request #24888 from ankush/allow_zero_valuation_SR
fix: Allow zero valuation in stock reconciliation
2021-03-23 13:58:46 +05:30
Ankush Menat
e76ecb8f74 fix: set valuation rate for customer items to zero
- In stock reconciliation always set valuation rate of customer provided
items to zero during validation.
- Let user know the valuation has been changed.
2021-03-23 13:01:21 +05:30
Ankush Menat
714b780868 test: customer item in stock reconciliation 2021-03-23 12:43:02 +05:30
pateljannat
453e07e32a fix: exclude cancelled salary slips 2021-03-23 11:18:57 +05:30
Ankush Menat
762d6e38f7 fix: Allow zero valuation in stock reconciliation
Stock reconciliation can not be done for customer provided item as they
have zero valuation. This change adds a checkbox in item table to allow
such items.

Related issue: ISS-20-21-10248
2021-03-23 11:18:04 +05:30
Marica
e6ad39038e chore: Allow changing Work Stations in WO. (#24897) 2021-03-23 10:46:03 +05:30
Deepesh Garg
ad9b65fcf2 fix: TDS check getting checked after reload (#24972) 2021-03-23 10:45:20 +05:30
Rohit Waghchaure
bde159a77d fix: total weight not set for free items 2021-03-22 23:36:48 +05:30
Deepesh Garg
48d5a65ef5 fix: Add test for pending shortfall update 2021-03-22 21:19:19 +05:30
Deepesh Garg
ea487b6c2e Revert "fix: GSTR B2C report" 2021-03-22 20:54:07 +05:30
Deepesh Garg
f112ce14cf fix: Pending shortfall update on processing loan security shortfall 2021-03-22 18:33:55 +05:30
Anupam
661b1e59c1 Merge branch 'develop' of https://github.com/frappe/erpnext into planning 2021-03-22 11:48:11 +05:30
Anupam
4980dd616b fix: resolving commits 2021-03-22 11:23:47 +05:30
Rucha Mahabal
5e1cb5e4bc fix: membership renewal validation (#24963) 2021-03-20 22:22:01 +05:30
Sagar Vora
a85959f574 fix: remove unwanted parameter in calculate_rate_and_amount (#24883)
* fix: remove unwanted parameter in calculate_rate_and_amount

* fix: translation syntax
2021-03-20 16:37:33 +05:30
Walstan Baptista
22054044a3 test: created a new user to test warehouse user perms (#24954)
Co-authored-by: Sagar Vora <sagar@resilient.tech>
2021-03-20 16:35:14 +05:30
Jannat Patel
08855182a3 test: fix test_loan for payroll module (#24946)
* test: fix test_loan for payroll module

* fix: minor style changes
2021-03-19 16:34:14 +05:30
rohitwaghchaure
081499c0c0 Merge pull request #24956 from rohitwaghchaure/revert-stock-balance-value-calculation-develop
fix: revert stock balance value calculation
2021-03-19 16:22:13 +05:30
Rohit Waghchaure
f21a55c8ef fix: revert stock balance value calculation 2021-03-19 16:19:34 +05:30
Deepesh Garg
9b0a9cc2c0 Merge pull request #24912 from deepeshgarg007/multi_currency_lcv_issues
fix: Allow user to update exchange rate in Multi-currency LCV
2021-03-18 21:20:06 +05:30
Deepesh Garg
adcf9a42bd Merge pull request #24916 from deepeshgarg007/nil_exempt_gstr_3b
fix(India): Incorrect Nil Exempt and Non GST amount in GSTR3B report
2021-03-18 21:02:51 +05:30
Walstan Baptista
6df61d217f test: created a new user to test child perms (#24943)
Co-authored-by: Sagar Vora <sagar@resilient.tech>
2021-03-18 19:23:59 +05:30
Sagar Vora
6ac11a04b0 test: added warehouse for TCS Item as it is a Stock Item (#24942) 2021-03-18 18:07:21 +05:30
Sagar Vora
8ee1146f72 test: add stock to avoid NegativeStockError (#24941) 2021-03-18 17:45:25 +05:30
Mohammad Hasnain Mohsin Rajan
192ab05869 ci: use ubuntu 18 specifically (#24904) 2021-03-18 17:12:12 +05:30
Afshan
a04091aaf7 fix: exclude current doc while validation. (#24914) 2021-03-18 16:40:43 +05:30
Sagar Vora
b134b89fb0 test: fix NegativeStockError (#24936) 2021-03-18 16:36:40 +05:30
pateljannat
a2068d9b98 feat: profitability report 2021-03-18 15:25:22 +05:30
Sagar Vora
78e576ee6a fix: default total_estimated_cost to zero (#24939)
Co-authored-by: walstanb <walstanb@gmail.com>
2021-03-18 15:23:52 +05:30
Ankush Menat
c0a9c391eb fix: hide alt tag if item is not shown in website 2021-03-18 14:07:24 +05:30
Deepesh Garg
d39055785a Merge pull request #24934 from Anuja-pawar/fix_report_issue_summary
fix: Report Issue Summary fix for zero issues
2021-03-18 12:24:43 +05:30
Anuja Pawar
9bf1083d9e fix: payment references from disappearing on selecting cost center (#24831)
Co-authored-by: Afshan <33727827+AfshanKhan@users.noreply.github.com>
2021-03-18 11:22:24 +05:30
Rushabh Mehta
14c3c5172d fix(minor): rearrange the cards on home workspace 2021-03-18 10:45:38 +05:30
Anuja P
2c8a38d9fa fix: report issue summary fix for zero issues 2021-03-18 10:36:46 +05:30
Sagar Vora
500f54e515 test: fix shift type not found (#24929) 2021-03-17 23:25:04 +05:30
Sagar Vora
52bbd4e182 test: clear Leave Period before running Leave Allocation tests (#24928) 2021-03-17 22:37:59 +05:30
Mohammad Hasnain Mohsin Rajan
7f906f9aaa chore: add sider config (#24892)
Co-authored-by: Sagar Vora <sagar@resilient.tech>
2021-03-17 20:06:35 +05:30
Sagar Vora
c647b6088a ci: update badge in README and add push event trigger (#24911) 2021-03-17 20:04:59 +05:30
Sagar Vora
19bb8c1137 ci: get branch name from GITHUB_REF if GITHUB_BASE_REF not available (#24913) 2021-03-17 20:03:54 +05:30
Sagar Vora
7645315424 test: set correct qty when creating subcontract transfer entry (#24903) 2021-03-17 20:01:21 +05:30
Sagar Vora
f4a6c7823a test: create new item instead of using _Test Item to prevent error (#24915) 2021-03-17 19:57:53 +05:30
Sagar Vora
cf3fc99b12 test: fix salary component not found; other optimisation (#24920) 2021-03-17 19:54:08 +05:30
Rucha Mahabal
cbd67e662f fix: calculate 80g certificate amount on validate for memberships (#24925) 2021-03-17 19:49:27 +05:30
Anurag Mishra
abf974daee fix: precision and formated document 2021-03-17 18:55:04 +05:30
Rohit Waghchaure
77add49c6a fix: don't club same free item 2021-03-17 18:49:54 +05:30
Deepesh Garg
f9f0e347ed fix: Remove print statement 2021-03-17 18:03:17 +05:30
Deepesh Garg
084ec9773e fix: Group nil exempted and non gst items separately 2021-03-17 18:00:08 +05:30
Anurag Mishra
23b6294f5c Merge pull request #24842 from resilient-tech/allow-duplicate-additional
fix(payroll): allow duplicate additional salaries
2021-03-17 17:39:52 +05:30
Deepesh Garg
56c20fb79f fix(India): Incorrect Nil Exempt and Non GST amount in GSTR3B report 2021-03-17 15:47:03 +05:30
Rohit Waghchaure
a9b1347600 fix: nonetype object has no attribute options 2021-03-17 14:30:34 +05:30
Rohit Waghchaure
ff70e61d7a feat: recursive product discount 2021-03-17 14:30:34 +05:30
Deepesh Garg
22f5ff8492 fix: Allow user to update exchange rate in Multi-currency LCV 2021-03-17 10:56:52 +05:30
Sagar Vora
68aaf12902 test: use _Test Company to avoid Holiday List error (#24902) 2021-03-17 10:06:05 +05:30
Sagar Vora
bce904cf97 test: fix Employee Not Found errors (#24906) 2021-03-17 10:03:30 +05:30
Sagar Vora
65d7f2c798 fix(Project): get correct holiday list when calculating dates; test fixes (#24901) 2021-03-17 10:00:35 +05:30
Andy Zhu
6117ac5aff fix: copy_parent_value_in_all_row function error 2021-03-17 13:53:02 +13:00
Raffael Meyer
344cb11a21 Merge branch 'develop' into improve_taxes_setup 2021-03-16 18:38:16 +01:00
Anurag Mishra
8fbb043190 Merge pull request #24824 from resilient-tech/fix-salary
refactor(payroll): simplified logic for additional salary
2021-03-16 21:42:10 +05:30
Rucha Mahabal
1482b2883f fix(Non Profit): Membership and Donation API fixes (#24900)
* fix: Donation fixes

- differentiate between subscription payment and payment

- issue with donation amount

* fix: existing membership validation

* fix: ignore subscription payments while capturing donations
2021-03-16 20:08:51 +05:30
Prssanna Desai
b74436d535 Merge pull request #24896 from prssanna/redesign-fixes 2021-03-16 16:08:15 +05:30
prssanna
1cdef8bd97 style: missing semicolon 2021-03-16 15:39:16 +05:30
prssanna
b8b89a02af fix: item variant dialog dropdown issue 2021-03-16 14:16:22 +05:30
prssanna
f1dbc021fc fix: issue web list style 2021-03-16 14:15:59 +05:30
Anurag Mishra
5cc322e01d Merge pull request #24877 from Anurag810/settings_for_eanbling_leave_notificstion
feat: Add checkbox for disabling leave notification in HR Settings
2021-03-16 13:23:16 +05:30
Afshan
46eb4b2f90 Merge branch 'develop' into settings_for_eanbling_leave_notificstion 2021-03-16 13:15:55 +05:30
Deepesh Garg
4470291243 Merge pull request #24893 from deepeshgarg007/add_account_method
fix: Add method for regional round off account back
2021-03-16 13:13:50 +05:30
Deepesh Garg
004f9e6b0c fix: Add method for regional round off account back 2021-03-16 13:09:59 +05:30
Anurag Mishra
6bafbffee0 fix: added also for leave applier as requested 2021-03-16 13:01:39 +05:30
Anurag Mishra
54482fd83f feat: added for disabling leave notification in HR settings 2021-03-16 13:01:39 +05:30
Rushabh Mehta
45735b35c4 fix(minor): login: set as Login to ERPNext 2021-03-16 12:22:31 +05:30
Rushabh Mehta
6ef213e5c6 fix(minor): patch add_state_code_for_ladakh 2021-03-16 11:59:54 +05:30
Marica
4d869906b6 Merge branch 'develop' into drop-shipping 2021-03-16 11:43:46 +05:30
Deepesh Garg
93f925fb98 fix: Unequal debit and credit issue on RCM Invoice (#24836)
* fix: Unequal debit and credit issue on RCM Invoice

* fix: Travis

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2021-03-15 18:04:42 +05:30
Raffael Meyer
db24b13a7d Merge branch 'develop' into improve_taxes_setup 2021-03-15 13:27:56 +01:00
Anurag Mishra
4f6f224544 Merge pull request #24622 from Anurag810/suplier_portal_fixes
fix: supplier was not able to Submit RFQ due to insufficient permission
2021-03-15 16:33:49 +05:30
Anurag Mishra
5e475f85b9 Merge branch 'develop' into suplier_portal_fixes 2021-03-15 16:21:55 +05:30
Raffael Meyer
6d5ea4cee8 Merge branch 'develop' into improve_taxes_setup 2021-03-15 11:40:39 +01:00
Marica
3575314260 Merge branch 'develop' into drop-shipping 2021-03-15 12:53:45 +05:30
Marica
4ceea333a7 fix: POS Opening Entry with empty balance detail rows (#24876) 2021-03-15 12:49:14 +05:30
Mohammad Hasnain Mohsin Rajan
46d5431bad fix: Github Action not failing when tests fail (#24867)
Co-authored-by: Sagar Vora <sagar@resilient.tech>
2021-03-15 11:17:19 +05:30
Anupam Kumar
ed42afc5e8 feat: price margin in buying (#24685) 2021-03-15 11:11:28 +05:30
Marica
5499401fcb Merge branch 'develop' into drop-shipping 2021-03-15 11:09:04 +05:30
Deepesh Garg
a2e4564464 fix: Prevent non sequential repayment entries 2021-03-15 10:32:38 +05:30
Anupam
d8f7a75eae feat: add total available stock field 2021-03-15 10:31:53 +05:30
Deepesh Garg
5165859e51 Merge pull request #24873 from GangaManoj/filter-bank-reconciliation
fix(Bank Reconciliation Tool): Filter Bank Account drop-down list
2021-03-15 10:21:14 +05:30
Deepesh Garg
61fb9bf869 fix: Loan Repayment entry cancellation on salary slip cancel 2021-03-14 21:25:21 +05:30
Ganga Manoj
ca03997ab5 fix(Bank Reconciliation): Filter Bank Account drop-down list 2021-03-13 22:21:07 +05:30
Deepesh Garg
e196be4d8a Merge pull request #24866 from resilient-tech/fix-test-import
test: fix import_doc call in test_shopify_settings
2021-03-13 19:12:15 +05:30
Sagar Vora
c5869d5b47 test: fix import_doc call in test_shopify_settings 2021-03-12 16:21:45 +05:30
Afshan
5d66a2b326 fix: added correct path in hooks (#24862) 2021-03-12 15:51:34 +05:30
marination
e685c787d2 fix: Sider (unused variables) 2021-03-12 14:24:09 +05:30
marination
86725a6580 fix: PO not created against all selected suppliers (drop shipping)
- Return list of created POs instead of first doc
- test case added
2021-03-12 14:12:46 +05:30
Mohammad Hasnain Mohsin Rajan
0f60f08f3e ci: Port CI test from Travis to Github Actions (#24846) 2021-03-12 14:09:52 +05:30
Sagar Vora
6727792aaf test: fix syntax error 2021-03-11 18:12:01 +05:30
Raffael Meyer
fb68aba30d Merge branch 'develop' into improve_taxes_setup 2021-03-11 13:17:44 +01:00
Sagar Vora
514122bf6f refactor(payroll): simplified logic for additional salary 2021-03-11 17:22:11 +05:30
Sagar Vora
5822b6d76f fix(payroll): allow duplicate additional salaries 2021-03-10 21:45:32 +05:30
Raffael Meyer
fbd810c2ae Merge branch 'develop' into improve_taxes_setup 2021-03-10 11:38:52 +01:00
barredterra
99c8b8efcf Merge branch 'develop' into improve_taxes_setup 2021-03-08 20:00:59 +01:00
barredterra
ebd1d08e55 refactor: taxes setup
Better structure of input data.
2021-03-08 19:53:50 +01:00
barredterra
25afad3dc1 refactor: extend taxes and charges setup
Add option to specify taxes and charges template depending on the CoA used. Differentiate between purchase, sales and item taxes. Maintain flexibility by using wildcards.
2021-03-04 21:11:31 +01:00
barredterra
dcfc3d7d12 fix: remove redundant calls to create_sales_tax 2021-03-04 19:29:55 +01:00
Anurag Mishra
5ec592d09c fix: supplier was not able to Submit RFQ due to in sufficient permission 2021-02-18 13:42:04 +05:30
Andy Zhu
b44af32628 Update accounts_controller.py
Updating Bin quantity based on doctype to optimize running efficiency.
2020-10-27 14:57:59 +13:00
Andy Zhu
1062d7eee0 fix: Update Items on Purchase Order
1. set warehouse using `get_item_warehouse`
2. update "reserved_qty" for sales order
2020-10-06 10:51:42 +13:00
Andy Zhu
760248911d fix: Update Items on Purchase Order
If user add rows or remove rows to update items on purchase order, the quantity in bin won't get updated.
This fix is not mature yet but to give an tempopary solution for fixing this issue.
2020-10-05 12:16:48 +13:00
489 changed files with 12188 additions and 5898 deletions

46
.github/helper/install.sh vendored Normal file
View File

@@ -0,0 +1,46 @@
#!/bin/bash
set -e
cd ~ || exit
sudo apt-get install redis-server
sudo apt install nodejs
sudo apt install npm
pip install frappe-bench
git clone https://github.com/frappe/frappe --branch "${GITHUB_BASE_REF:-${GITHUB_REF##*/}}" --depth 1
bench init --skip-assets --frappe-path ~/frappe --python "$(which python)" frappe-bench
mkdir ~/frappe-bench/sites/test_site
cp -r "${GITHUB_WORKSPACE}/.github/helper/site_config.json" ~/frappe-bench/sites/test_site/
mysql --host 127.0.0.1 --port 3306 -u root -e "SET GLOBAL character_set_server = 'utf8mb4'"
mysql --host 127.0.0.1 --port 3306 -u root -e "SET GLOBAL collation_server = 'utf8mb4_unicode_ci'"
mysql --host 127.0.0.1 --port 3306 -u root -e "CREATE USER 'test_frappe'@'localhost' IDENTIFIED BY 'test_frappe'"
mysql --host 127.0.0.1 --port 3306 -u root -e "CREATE DATABASE test_frappe"
mysql --host 127.0.0.1 --port 3306 -u root -e "GRANT ALL PRIVILEGES ON \`test_frappe\`.* TO 'test_frappe'@'localhost'"
mysql --host 127.0.0.1 --port 3306 -u root -e "UPDATE mysql.user SET Password=PASSWORD('travis') WHERE User='root'"
mysql --host 127.0.0.1 --port 3306 -u root -e "FLUSH PRIVILEGES"
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
sudo apt-get install libcups2-dev
cd ~/frappe-bench || exit
sed -i 's/watch:/# watch:/g' Procfile
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 erpnext "${GITHUB_WORKSPACE}"
bench start &
bench --site test_site reinstall --yes

38
.github/helper/semgrep_rules/README.md vendored Normal file
View File

@@ -0,0 +1,38 @@
# Semgrep linting
## What is semgrep?
Semgrep or "semantic grep" is language agnostic static analysis tool. In simple terms semgrep is syntax-aware `grep`, so unlike regex it doesn't get confused by different ways of writing same thing or whitespaces or code split in multiple lines etc.
Example:
To check if a translate function is using f-string or not the regex would be `r"_\(\s*f[\"']"` while equivalent rule in semgrep would be `_(f"...")`. As semgrep knows grammer of language it takes care of unnecessary whitespace, type of quotation marks etc.
You can read more such examples in `.github/helper/semgrep_rules` directory.
# Why/when to use this?
We want to maintain quality of contributions, at the same time remembering all the good practices can be pain to deal with while evaluating contributions. Using semgrep if you can translate "best practice" into a rule then it can automate the task for us.
## Running locally
Install semgrep using homebrew `brew install semgrep` or pip `pip install semgrep`.
To run locally use following command:
`semgrep --config=.github/helper/semgrep_rules [file/folder names]`
## Testing
semgrep allows testing the tests. Refer to this page: https://semgrep.dev/docs/writing-rules/testing-rules/
When writing new rules you should write few positive and few negative cases as shown in the guide and current tests.
To run current tests: `semgrep --test --test-ignore-todo .github/helper/semgrep_rules`
## Reference
If you are new to Semgrep read following pages to get started on writing/modifying rules:
- https://semgrep.dev/docs/getting-started/
- https://semgrep.dev/docs/writing-rules/rule-syntax
- https://semgrep.dev/docs/writing-rules/pattern-examples/
- https://semgrep.dev/docs/writing-rules/rule-ideas/#common-use-cases

View File

@@ -0,0 +1,28 @@
import frappe
from frappe import _, flt
from frappe.model.document import Document
def on_submit(self):
if self.value_of_goods == 0:
frappe.throw(_('Value of goods cannot be 0'))
# ruleid: frappe-modifying-after-submit
self.status = 'Submitted'
def on_submit(self):
if flt(self.per_billed) < 100:
self.update_billing_status()
else:
# todook: frappe-modifying-after-submit
self.status = "Completed"
self.db_set("status", "Completed")
class TestDoc(Document):
pass
def validate(self):
#ruleid: frappe-modifying-child-tables-while-iterating
for item in self.child_table:
if item.value < 0:
self.remove(item)

View File

@@ -0,0 +1,74 @@
# This file specifies rules for correctness according to how frappe doctype data model works.
rules:
- id: frappe-modifying-after-submit
patterns:
- pattern: self.$ATTR = ...
- pattern-inside: |
def on_submit(self, ...):
...
- metavariable-regex:
metavariable: '$ATTR'
# this is negative look-ahead, add more attrs to ignore like (ignore|ignore_this_too|ignore_me)
regex: '^(?!status_updater)(.*)$'
message: |
Doctype modified after submission. Please check if modification of self.$ATTR is commited to database.
languages: [python]
severity: ERROR
- id: frappe-modifying-after-cancel
patterns:
- pattern: self.$ATTR = ...
- pattern-inside: |
def on_cancel(self, ...):
...
- metavariable-regex:
metavariable: '$ATTR'
regex: '^(?!ignore_linked_doctypes|status_updater)(.*)$'
message: |
Doctype modified after cancellation. Please check if modification of self.$ATTR is commited to database.
languages: [python]
severity: ERROR
- id: frappe-print-function-in-doctypes
pattern: print(...)
message: |
Did you mean to leave this print statement in? Consider using msgprint or logger instead of print statement.
languages: [python]
severity: WARNING
paths:
exclude:
- test_*.py
include:
- "*/**/doctype/*"
- id: frappe-modifying-child-tables-while-iterating
pattern-either:
- pattern: |
for $ROW in self.$TABLE:
...
self.remove(...)
- pattern: |
for $ROW in self.$TABLE:
...
self.append(...)
message: |
Child table being modified while iterating on it.
languages: [python]
severity: ERROR
paths:
include:
- "*/**/doctype/*"
- id: frappe-same-key-assigned-twice
pattern-either:
- pattern: |
{..., $X: $A, ..., $X: $B, ...}
- pattern: |
dict(..., ($X, $A), ..., ($X, $B), ...)
- pattern: |
_dict(..., ($X, $A), ..., ($X, $B), ...)
message: |
key `$X` is uselessly assigned twice. This could be a potential bug.
languages: [python]
severity: ERROR

View File

@@ -0,0 +1,6 @@
def function_name(input):
# ruleid: frappe-codeinjection-eval
eval(input)
# ok: frappe-codeinjection-eval
eval("1 + 1")

View File

@@ -0,0 +1,25 @@
rules:
- id: frappe-codeinjection-eval
patterns:
- pattern-not: eval("...")
- pattern: eval(...)
message: |
Detected the use of eval(). eval() can be dangerous if used to evaluate
dynamic content. Avoid it or use safe_eval().
languages: [python]
severity: ERROR
- id: frappe-sqli-format-strings
patterns:
- pattern-inside: |
@frappe.whitelist()
def $FUNC(...):
...
- pattern-either:
- pattern: frappe.db.sql("..." % ...)
- pattern: frappe.db.sql(f"...", ...)
- pattern: frappe.db.sql("...".format(...), ...)
message: |
Detected use of raw string formatting for SQL queries. This can lead to sql injection vulnerabilities. Refer security guidelines - https://github.com/frappe/erpnext/wiki/Code-Security-Guidelines
languages: [python]
severity: WARNING

View File

@@ -0,0 +1,37 @@
// ruleid: frappe-translation-empty-string
__("")
// ruleid: frappe-translation-empty-string
__('')
// ok: frappe-translation-js-formatting
__('Welcome {0}, get started with ERPNext in just a few clicks.', [full_name]);
// ruleid: frappe-translation-js-formatting
__(`Welcome ${full_name}, get started with ERPNext in just a few clicks.`);
// ok: frappe-translation-js-formatting
__('This is fine');
// ok: frappe-translation-trailing-spaces
__('This is fine');
// ruleid: frappe-translation-trailing-spaces
__(' this is not ok ');
// ruleid: frappe-translation-trailing-spaces
__('this is not ok ');
// ruleid: frappe-translation-trailing-spaces
__(' this is not ok');
// ok: frappe-translation-js-splitting
__('You have {0} subscribers in your mailing list.', [subscribers.length])
// todoruleid: frappe-translation-js-splitting
__('You have') + subscribers.length + __('subscribers in your mailing list.')
// ruleid: frappe-translation-js-splitting
__('You have' + 'subscribers in your mailing list.')
// ruleid: frappe-translation-js-splitting
__('You have {0} subscribers' +
'in your mailing list', [subscribers.length])

View File

@@ -0,0 +1,53 @@
# Examples taken from https://frappeframework.com/docs/user/en/translations
# This file is used for testing the tests.
from frappe import _
full_name = "Jon Doe"
# ok: frappe-translation-python-formatting
_('Welcome {0}, get started with ERPNext in just a few clicks.').format(full_name)
# ruleid: frappe-translation-python-formatting
_('Welcome %s, get started with ERPNext in just a few clicks.' % full_name)
# ruleid: frappe-translation-python-formatting
_('Welcome %(name)s, get started with ERPNext in just a few clicks.' % {'name': full_name})
# ruleid: frappe-translation-python-formatting
_('Welcome {0}, get started with ERPNext in just a few clicks.'.format(full_name))
subscribers = ["Jon", "Doe"]
# ok: frappe-translation-python-formatting
_('You have {0} subscribers in your mailing list.').format(len(subscribers))
# ruleid: frappe-translation-python-splitting
_('You have') + len(subscribers) + _('subscribers in your mailing list.')
# ruleid: frappe-translation-python-splitting
_('You have {0} subscribers \
in your mailing list').format(len(subscribers))
# ok: frappe-translation-python-splitting
_('You have {0} subscribers') \
+ 'in your mailing list'
# ruleid: frappe-translation-trailing-spaces
msg = _(" You have {0} pending invoice ")
# ruleid: frappe-translation-trailing-spaces
msg = _("You have {0} pending invoice ")
# ruleid: frappe-translation-trailing-spaces
msg = _(" You have {0} pending invoice")
# ok: frappe-translation-trailing-spaces
msg = ' ' + _("You have {0} pending invoices") + ' '
# ruleid: frappe-translation-python-formatting
_(f"can not format like this - {subscribers}")
# ruleid: frappe-translation-python-splitting
_(f"what" + f"this is also not cool")
# ruleid: frappe-translation-empty-string
_("")
# ruleid: frappe-translation-empty-string
_('')

View File

@@ -0,0 +1,63 @@
rules:
- id: frappe-translation-empty-string
pattern-either:
- pattern: _("")
- pattern: __("")
message: |
Empty string is useless for translation.
Please refer: https://frappeframework.com/docs/user/en/translations
languages: [python, javascript, json]
severity: ERROR
- id: frappe-translation-trailing-spaces
pattern-either:
- pattern: _("=~/(^[ \t]+|[ \t]+$)/")
- pattern: __("=~/(^[ \t]+|[ \t]+$)/")
message: |
Trailing or leading whitespace not allowed in translate strings.
Please refer: https://frappeframework.com/docs/user/en/translations
languages: [python, javascript, json]
severity: ERROR
- id: frappe-translation-python-formatting
pattern-either:
- pattern: _("..." % ...)
- pattern: _("...".format(...))
- pattern: _(f"...")
message: |
Only positional formatters are allowed and formatting should not be done before translating.
Please refer: https://frappeframework.com/docs/user/en/translations
languages: [python]
severity: ERROR
- id: frappe-translation-js-formatting
patterns:
- pattern: __(`...`)
- pattern-not: __("...")
message: |
Template strings are not allowed for text formatting.
Please refer: https://frappeframework.com/docs/user/en/translations
languages: [javascript, json]
severity: ERROR
- id: frappe-translation-python-splitting
pattern-either:
- pattern: _(...) + ... + _(...)
- pattern: _("..." + "...")
- pattern-regex: '_\([^\)]*\\\s*'
message: |
Do not split strings inside translate function. Do not concatenate using translate functions.
Please refer: https://frappeframework.com/docs/user/en/translations
languages: [python]
severity: ERROR
- id: frappe-translation-js-splitting
pattern-either:
- pattern-regex: '__\([^\)]*[\+\\]\s*'
- pattern: __('...' + '...')
- pattern: __('...') + __('...')
message: |
Do not split strings inside translate function. Do not concatenate using translate functions.
Please refer: https://frappeframework.com/docs/user/en/translations
languages: [javascript, json]
severity: ERROR

31
.github/helper/semgrep_rules/ux.py vendored Normal file
View File

@@ -0,0 +1,31 @@
import frappe
from frappe import msgprint, throw, _
# ruleid: frappe-missing-translate-function
throw("Error Occured")
# ruleid: frappe-missing-translate-function
frappe.throw("Error Occured")
# ruleid: frappe-missing-translate-function
frappe.msgprint("Useful message")
# ruleid: frappe-missing-translate-function
msgprint("Useful message")
# ok: frappe-missing-translate-function
translatedmessage = _("Hello")
# ok: frappe-missing-translate-function
throw(translatedmessage)
# ok: frappe-missing-translate-function
msgprint(translatedmessage)
# ok: frappe-missing-translate-function
msgprint(_("Helpful message"))
# ok: frappe-missing-translate-function
frappe.throw(_("Error occured"))

15
.github/helper/semgrep_rules/ux.yml vendored Normal file
View File

@@ -0,0 +1,15 @@
rules:
- id: frappe-missing-translate-function
pattern-either:
- patterns:
- pattern: frappe.msgprint("...", ...)
- pattern-not: frappe.msgprint(_("..."), ...)
- pattern-not: frappe.msgprint(__("..."), ...)
- patterns:
- pattern: frappe.throw("...", ...)
- pattern-not: frappe.throw(_("..."), ...)
- pattern-not: frappe.throw(__("..."), ...)
message: |
All user facing text must be wrapped in translate function. Please refer to translation documentation. https://frappeframework.com/docs/user/en/guides/basics/translations
languages: [python, javascript, json]
severity: ERROR

View File

@@ -1,4 +1,6 @@
{
"db_host": "127.0.0.1",
"db_port": 3306,
"db_name": "test_frappe",
"db_password": "test_frappe",
"auto_email_id": "test@example.com",

108
.github/workflows/ci-tests.yml vendored Normal file
View File

@@ -0,0 +1,108 @@
name: CI
on: [pull_request, workflow_dispatch, push]
jobs:
test:
runs-on: ubuntu-18.04
strategy:
fail-fast: false
matrix:
include:
- TYPE: "server"
JOB_NAME: "Server"
RUN_COMMAND: cd ~/frappe-bench/ && bench --site test_site run-tests --app erpnext --coverage
- TYPE: "patch"
JOB_NAME: "Patch"
RUN_COMMAND: cd ~/frappe-bench/ && wget http://build.erpnext.com/20171108_190013_955977f8_database.sql.gz && bench --site test_site --force restore ~/frappe-bench/20171108_190013_955977f8_database.sql.gz && bench --site test_site migrate
name: ${{ matrix.JOB_NAME }}
services:
mysql:
image: mariadb:10.3
env:
MYSQL_ALLOW_EMPTY_PASSWORD: YES
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
steps:
- name: Clone
uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: 3.6
- name: Add to Hosts
run: echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts
- name: Cache pip
uses: actions/cache@v2
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
${{ runner.os }}-
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install
run: bash ${GITHUB_WORKSPACE}/.github/helper/install.sh
- name: Run Tests
run: ${{ matrix.RUN_COMMAND }}
env:
TYPE: ${{ matrix.TYPE }}
- name: Coverage - Pull Request
if: matrix.TYPE == 'server' && github.event_name == 'pull_request'
run: |
cp ~/frappe-bench/sites/.coverage ${GITHUB_WORKSPACE}
cd ${GITHUB_WORKSPACE}
pip install coveralls==2.2.0
pip install coverage==4.5.4
coveralls --service=github
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_TOKEN }}
COVERALLS_SERVICE_NAME: github
- name: Coverage - Push
if: matrix.TYPE == 'server' && github.event_name == 'push'
run: |
cp ~/frappe-bench/sites/.coverage ${GITHUB_WORKSPACE}
cd ${GITHUB_WORKSPACE}
pip install coveralls==2.2.0
pip install coverage==4.5.4
coveralls --service=github-actions
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_TOKEN }}
COVERALLS_SERVICE_NAME: github-actions

24
.github/workflows/semgrep.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
name: Semgrep
on:
pull_request:
branches:
- develop
jobs:
semgrep:
name: Frappe Linter
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup python3
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Run semgrep
run: |
python -m pip install -q semgrep
git fetch origin $GITHUB_BASE_REF:$GITHUB_BASE_REF -q
files=$(git diff --name-only --diff-filter=d $GITHUB_BASE_REF)
[[ -d .github/helper/semgrep_rules ]] && semgrep --severity ERROR --config=.github/helper/semgrep_rules --quiet --error $files
semgrep --config="r/python.lang.correctness" --quiet --error $files
[[ -d .github/helper/semgrep_rules ]] && semgrep --severity WARNING --severity INFO --config=.github/helper/semgrep_rules --quiet $files

View File

@@ -1,69 +0,0 @@
language: python
dist: trusty
git:
depth: 1
cache:
- pip
addons:
hosts: test_site
mariadb: 10.3
jobs:
include:
- name: "Python 3.6 Server Side Test"
python: 3.6
script: bench --site test_site run-tests --app erpnext --coverage
- name: "Python 3.6 Patch Test"
python: 3.6
before_script:
- wget http://build.erpnext.com/20171108_190013_955977f8_database.sql.gz
- bench --site test_site --force restore ~/frappe-bench/20171108_190013_955977f8_database.sql.gz
script: bench --site test_site migrate
install:
- cd ~
- nvm install 10
- pip install frappe-bench
- git clone https://github.com/frappe/frappe --branch $TRAVIS_BRANCH --depth 1
- bench init --skip-assets --frappe-path ~/frappe --python $(which python) frappe-bench
- mkdir ~/frappe-bench/sites/test_site
- cp -r $TRAVIS_BUILD_DIR/.travis/site_config.json ~/frappe-bench/sites/test_site/
- mysql -u root -e "SET GLOBAL character_set_server = 'utf8mb4'"
- mysql -u root -e "SET GLOBAL collation_server = 'utf8mb4_unicode_ci'"
- mysql -u root -e "CREATE DATABASE test_frappe"
- mysql -u root -e "CREATE USER 'test_frappe'@'localhost' IDENTIFIED BY 'test_frappe'"
- mysql -u root -e "GRANT ALL PRIVILEGES ON \`test_frappe\`.* TO 'test_frappe'@'localhost'"
- mysql -u root -e "UPDATE mysql.user SET Password=PASSWORD('travis') WHERE User='root'"
- mysql -u root -e "FLUSH PRIVILEGES"
- 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
- sudo apt-get install libcups2-dev
- cd ~/frappe-bench
- sed -i 's/watch:/# watch:/g' Procfile
- 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 erpnext $TRAVIS_BUILD_DIR
- bench start &
- bench --site test_site reinstall --yes
after_script:
- pip install coverage==4.5.4
- pip install python-coveralls
- coveralls -b apps/erpnext -d ../../sites/.coverage

View File

@@ -5,7 +5,7 @@
<p>ERP made simple</p>
</p>
[![Build Status](https://api.travis-ci.com/frappe/erpnext.svg?branch=develop)](https://travis-ci.com/frappe/erpnext)
[![CI](https://github.com/frappe/erpnext/actions/workflows/ci-tests.yml/badge.svg?branch=develop)](https://github.com/frappe/erpnext/actions/workflows/ci-tests.yml)
[![Open Source Helpers](https://www.codetriage.com/frappe/erpnext/badges/users.svg)](https://www.codetriage.com/frappe/erpnext)
[![Coverage Status](https://coveralls.io/repos/github/frappe/erpnext/badge.svg?branch=develop)](https://coveralls.io/github/frappe/erpnext?branch=develop)
@@ -39,6 +39,10 @@ ERPNext is built on the [Frappe Framework](https://github.com/frappe/frappe), a
---
### Containerized Installation
Use docker to deploy ERPNext in production or for development of [Frappe](https://github.com/frappe/frappe) apps. See https://github.com/frappe/frappe_docker for more details.
### Full Install
The Easy Way: our install script for bench will install all dependencies (e.g. MariaDB). See https://github.com/frappe/bench for more details.

View File

@@ -5,7 +5,7 @@ import frappe
from erpnext.hooks import regional_overrides
from frappe.utils import getdate
__version__ = '13.0.2'
__version__ = '13.3.1'
def get_default_company(user=None):
'''Get default company for user'''

View File

@@ -13,7 +13,7 @@ class BalanceMismatchError(frappe.ValidationError): pass
class Account(NestedSet):
nsm_parent_field = 'parent_account'
def on_update(self):
if frappe.local.flags.ignore_on_update:
if frappe.local.flags.ignore_update_nsm:
return
else:
super(Account, self).on_update()
@@ -214,6 +214,7 @@ class Account(NestedSet):
if parent_value_changed:
doc.save()
@frappe.whitelist()
def convert_group_to_ledger(self):
if self.check_if_child_exists():
throw(_("Account with child nodes cannot be converted to ledger"))
@@ -224,6 +225,7 @@ class Account(NestedSet):
self.save()
return 1
@frappe.whitelist()
def convert_ledger_to_group(self):
if self.check_gle_exists():
throw(_("Account with existing transaction can not be converted to group."))

View File

@@ -57,10 +57,10 @@ def create_charts(company, chart_template=None, existing_company=None, custom_ch
# Rebuild NestedSet HSM tree for Account Doctype
# after all accounts are already inserted.
frappe.local.flags.ignore_on_update = True
frappe.local.flags.ignore_update_nsm = True
_import_accounts(chart, None, None, root_account=True)
rebuild_tree("Account", "parent_account")
frappe.local.flags.ignore_on_update = False
frappe.local.flags.ignore_update_nsm = False
def add_suffix_if_duplicate(account_name, account_number, accounts):
if account_number:

View File

@@ -39,6 +39,7 @@ class AccountingPeriod(Document):
frappe.throw(_("Accounting Period overlaps with {0}")
.format(existing_accounting_period[0].get("name")), OverlapError)
@frappe.whitelist()
def get_doctypes_for_closing(self):
docs_for_closing = []
doctypes = ["Sales Invoice", "Purchase Invoice", "Journal Entry", "Payroll Entry", \

View File

@@ -11,36 +11,36 @@ from erpnext.accounts.doctype.accounting_period.accounting_period import Overlap
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
class TestAccountingPeriod(unittest.TestCase):
def test_overlap(self):
ap1 = create_accounting_period(start_date = "2018-04-01",
end_date = "2018-06-30", company = "Wind Power LLC")
ap1.save()
def test_overlap(self):
ap1 = create_accounting_period(start_date = "2018-04-01",
end_date = "2018-06-30", company = "Wind Power LLC")
ap1.save()
ap2 = create_accounting_period(start_date = "2018-06-30",
end_date = "2018-07-10", company = "Wind Power LLC", period_name = "Test Accounting Period 1")
self.assertRaises(OverlapError, ap2.save)
ap2 = create_accounting_period(start_date = "2018-06-30",
end_date = "2018-07-10", company = "Wind Power LLC", period_name = "Test Accounting Period 1")
self.assertRaises(OverlapError, ap2.save)
def test_accounting_period(self):
ap1 = create_accounting_period(period_name = "Test Accounting Period 2")
ap1.save()
def test_accounting_period(self):
ap1 = create_accounting_period(period_name = "Test Accounting Period 2")
ap1.save()
doc = create_sales_invoice(do_not_submit=1, cost_center = "_Test Company - _TC", warehouse = "Stores - _TC")
self.assertRaises(ClosedAccountingPeriod, doc.submit)
doc = create_sales_invoice(do_not_submit=1, cost_center="_Test Company - _TC", warehouse="Stores - _TC")
self.assertRaises(ClosedAccountingPeriod, doc.submit)
def tearDown(self):
for d in frappe.get_all("Accounting Period"):
frappe.delete_doc("Accounting Period", d.name)
def tearDown(self):
for d in frappe.get_all("Accounting Period"):
frappe.delete_doc("Accounting Period", d.name)
def create_accounting_period(**args):
args = frappe._dict(args)
args = frappe._dict(args)
accounting_period = frappe.new_doc("Accounting Period")
accounting_period.start_date = args.start_date or nowdate()
accounting_period.end_date = args.end_date or add_months(nowdate(), 1)
accounting_period.company = args.company or "_Test Company"
accounting_period.period_name =args.period_name or "_Test_Period_Name_1"
accounting_period.append("closed_documents", {
"document_type": 'Sales Invoice', "closed": 1
})
accounting_period = frappe.new_doc("Accounting Period")
accounting_period.start_date = args.start_date or nowdate()
accounting_period.end_date = args.end_date or add_months(nowdate(), 1)
accounting_period.company = args.company or "_Test Company"
accounting_period.period_name =args.period_name or "_Test_Period_Name_1"
accounting_period.append("closed_documents", {
"document_type": 'Sales Invoice', "closed": 1
})
return accounting_period
return accounting_period

View File

@@ -7,25 +7,30 @@
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"auto_accounting_for_stock",
"acc_frozen_upto",
"frozen_accounts_modifier",
"determine_address_tax_category_from",
"accounts_transactions_settings_section",
"over_billing_allowance",
"column_break_4",
"credit_controller",
"check_supplier_invoice_uniqueness",
"role_allowed_to_over_bill",
"make_payment_via_journal_entry",
"column_break_11",
"check_supplier_invoice_uniqueness",
"unlink_payment_on_cancellation_of_invoice",
"unlink_advance_payment_on_cancelation_of_order",
"book_asset_depreciation_entry_automatically",
"add_taxes_from_item_tax_template",
"automatically_fetch_payment_terms",
"delete_linked_ledger_entries",
"book_asset_depreciation_entry_automatically",
"unlink_advance_payment_on_cancelation_of_order",
"tax_settings_section",
"determine_address_tax_category_from",
"column_break_19",
"add_taxes_from_item_tax_template",
"period_closing_settings_section",
"acc_frozen_upto",
"frozen_accounts_modifier",
"column_break_4",
"credit_controller",
"deferred_accounting_settings_section",
"automatically_process_deferred_accounting_entry",
"book_deferred_entries_based_on",
"column_break_18",
"automatically_process_deferred_accounting_entry",
"book_deferred_entries_via_journal_entry",
"submit_journal_entries",
"print_settings",
@@ -39,15 +44,6 @@
"use_custom_cash_flow"
],
"fields": [
{
"default": "1",
"description": "If enabled, the system will post accounting entries for inventory automatically",
"fieldname": "auto_accounting_for_stock",
"fieldtype": "Check",
"hidden": 1,
"in_list_view": 1,
"label": "Make Accounting Entry For Every Stock Movement"
},
{
"description": "Accounting entries are frozen up to this date. Nobody can create or modify entries except users with the role specified below",
"fieldname": "acc_frozen_upto",
@@ -93,6 +89,7 @@
"default": "0",
"fieldname": "make_payment_via_journal_entry",
"fieldtype": "Check",
"hidden": 1,
"label": "Make Payment via Journal Entry"
},
{
@@ -226,6 +223,36 @@
"fieldname": "delete_linked_ledger_entries",
"fieldtype": "Check",
"label": "Delete Accounting and Stock Ledger Entries on deletion of Transaction"
},
{
"description": "Users with this role are allowed to over bill above the allowance percentage",
"fieldname": "role_allowed_to_over_bill",
"fieldtype": "Link",
"label": "Role Allowed to Over Bill ",
"options": "Role"
},
{
"fieldname": "period_closing_settings_section",
"fieldtype": "Section Break",
"label": "Period Closing Settings"
},
{
"fieldname": "accounts_transactions_settings_section",
"fieldtype": "Section Break",
"label": "Transactions Settings"
},
{
"fieldname": "column_break_11",
"fieldtype": "Column Break"
},
{
"fieldname": "tax_settings_section",
"fieldtype": "Section Break",
"label": "Tax Settings"
},
{
"fieldname": "column_break_19",
"fieldtype": "Column Break"
}
],
"icon": "icon-cog",
@@ -233,7 +260,7 @@
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2021-01-05 13:04:00.118892",
"modified": "2021-04-30 15:25:10.381008",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts Settings",

View File

@@ -30,5 +30,5 @@ class AccountsSettings(Document):
def enable_payment_schedule_in_print(self):
show_in_print = cint(self.show_payment_schedule_in_print)
for doctype in ("Sales Order", "Sales Invoice", "Purchase Order", "Purchase Invoice"):
make_property_setter(doctype, "due_date", "print_hide", show_in_print, "Check")
make_property_setter(doctype, "payment_schedule", "print_hide", 0 if show_in_print else 1, "Check")
make_property_setter(doctype, "due_date", "print_hide", show_in_print, "Check", validate_fields_for_doctype=False)
make_property_setter(doctype, "payment_schedule", "print_hide", 0 if show_in_print else 1, "Check", validate_fields_for_doctype=False)

View File

@@ -42,10 +42,9 @@ let add_fields_to_mapping_table = function (frm) {
});
});
frappe.meta.get_docfield("Bank Transaction Mapping", "bank_transaction_field",
frm.doc.name).options = options;
frm.fields_dict.bank_transaction_mapping.grid.refresh();
frm.fields_dict.bank_transaction_mapping.grid.update_docfield_property(
'bank_transaction_field', 'options', options
);
};
erpnext.integrations.refreshPlaidLink = class refreshPlaidLink {

View File

@@ -12,6 +12,7 @@ form_grid_templates = {
}
class BankClearance(Document):
@frappe.whitelist()
def get_payment_entries(self):
if not (self.from_date and self.to_date):
frappe.throw(_("From Date and To Date are Mandatory"))
@@ -108,6 +109,7 @@ class BankClearance(Document):
row.update(d)
self.total_amount += flt(amount)
@frappe.whitelist()
def update_clearance_date(self):
clearance_date_updated = False
for d in self.get('payment_entries'):

View File

@@ -8,6 +8,7 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
return {
filters: {
company: ["in", frm.doc.company],
'is_company_account': 1
},
};
});
@@ -77,8 +78,7 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
if (
frm.doc.bank_account &&
frm.doc.bank_statement_from_date &&
frm.doc.bank_statement_to_date &&
frm.doc.bank_statement_closing_balance
frm.doc.bank_statement_to_date
) {
frm.trigger("render_chart");
frm.trigger("render");

View File

@@ -39,13 +39,13 @@
"depends_on": "eval: doc.bank_account",
"fieldname": "bank_statement_from_date",
"fieldtype": "Date",
"label": "Bank Statement From Date"
"label": "From Date"
},
{
"depends_on": "eval: doc.bank_statement_from_date",
"fieldname": "bank_statement_to_date",
"fieldtype": "Date",
"label": "Bank Statement To Date"
"label": "To Date"
},
{
"fieldname": "column_break_2",
@@ -63,11 +63,10 @@
"depends_on": "eval: doc.bank_statement_to_date",
"fieldname": "bank_statement_closing_balance",
"fieldtype": "Currency",
"label": "Bank Statement Closing Balance",
"label": "Closing Balance",
"options": "Currency"
},
{
"depends_on": "eval: doc.bank_statement_closing_balance",
"fieldname": "section_break_1",
"fieldtype": "Section Break",
"label": "Reconcile"
@@ -90,7 +89,7 @@
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2021-02-02 01:35:53.043578",
"modified": "2021-04-21 11:13:49.831769",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Bank Reconciliation Tool",

View File

@@ -239,6 +239,7 @@ frappe.ui.form.on("Bank Statement Import", {
"withdrawal",
"description",
"reference_number",
"bank_account"
],
},
});
@@ -532,43 +533,4 @@ frappe.ui.form.on("Bank Statement Import", {
</table>
`);
},
show_missing_link_values(frm, missing_link_values) {
let can_be_created_automatically = missing_link_values.every(
(d) => d.has_one_mandatory_field
);
let html = missing_link_values
.map((d) => {
let doctype = d.doctype;
let values = d.missing_values;
return `
<h5>${doctype}</h5>
<ul>${values.map((v) => `<li>${v}</li>`).join("")}</ul>
`;
})
.join("");
if (can_be_created_automatically) {
// prettier-ignore
let message = __('There are some linked records which needs to be created before we can import your file. Do you want to create the following missing records automatically?');
frappe.confirm(message + html, () => {
frm.call("create_missing_link_values", {
missing_link_values,
}).then((r) => {
let records = r.message;
frappe.msgprint(__(
"Created {0} records successfully.", [
records.length,
]
));
});
});
} else {
frappe.msgprint(
// prettier-ignore
__('The following records needs to be created before we can import your file.') + html
);
}
},
});

View File

@@ -146,7 +146,7 @@
},
{
"depends_on": "eval:!doc.__islocal && !doc.import_file\n",
"description": "Must be a publicly accessible Google Sheets URL",
"description": "Must be a publicly accessible Google Sheets URL and adding Bank Account column is necessary for importing via Google Sheets",
"fieldname": "google_sheets_url",
"fieldtype": "Data",
"label": "Import from Google Sheets"
@@ -202,7 +202,7 @@
],
"hide_toolbar": 1,
"links": [],
"modified": "2021-02-10 19:29:59.027325",
"modified": "2021-05-12 14:17:37.777246",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Bank Statement Import",
@@ -224,4 +224,4 @@
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}
}

View File

@@ -47,6 +47,13 @@ class BankStatementImport(DataImport):
def start_import(self):
preview = frappe.get_doc("Bank Statement Import", self.name).get_preview_from_template(
self.import_file, self.google_sheets_url
)
if 'Bank Account' not in json.dumps(preview):
frappe.throw(_("Please add the Bank Account column"))
from frappe.core.page.background_jobs.background_jobs import get_info
from frappe.utils.scheduler import is_scheduler_inactive
@@ -67,6 +74,7 @@ class BankStatementImport(DataImport):
data_import=self.name,
bank_account=self.bank_account,
import_file_path=self.import_file,
google_sheets_url=self.google_sheets_url,
bank=self.bank,
template_options=self.template_options,
now=frappe.conf.developer_mode or frappe.flags.in_test,
@@ -90,18 +98,20 @@ def download_errored_template(data_import_name):
data_import = frappe.get_doc("Bank Statement Import", data_import_name)
data_import.export_errored_rows()
def start_import(data_import, bank_account, import_file_path, bank, template_options):
def start_import(data_import, bank_account, import_file_path, google_sheets_url, bank, template_options):
"""This method runs in background job"""
update_mapping_db(bank, template_options)
data_import = frappe.get_doc("Bank Statement Import", data_import)
file = import_file_path if import_file_path else google_sheets_url
import_file = ImportFile("Bank Transaction", file = import_file_path, import_type="Insert New Records")
import_file = ImportFile("Bank Transaction", file = file, import_type="Insert New Records")
data = import_file.raw_data
add_bank_account(data, bank_account)
write_files(import_file, data)
if import_file_path:
add_bank_account(data, bank_account)
write_files(import_file, data)
try:
i = Importer(data_import.reference_doctype, data_import=data_import)

View File

@@ -175,22 +175,24 @@
},
{
"fieldname": "deposit",
"oldfieldname": "debit",
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Deposit"
"label": "Deposit",
"oldfieldname": "debit",
"options": "currency"
},
{
"fieldname": "withdrawal",
"oldfieldname": "credit",
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Withdrawal"
"label": "Withdrawal",
"oldfieldname": "credit",
"options": "currency"
}
],
"is_submittable": 1,
"links": [],
"modified": "2020-12-30 19:40:54.221070",
"modified": "2021-04-14 17:31:58.963529",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Bank Transaction",

View File

@@ -15,12 +15,14 @@ from erpnext.accounts.doctype.pos_profile.test_pos_profile import make_pos_profi
test_dependencies = ["Item", "Cost Center"]
class TestBankTransaction(unittest.TestCase):
def setUp(self):
@classmethod
def setUpClass(cls):
make_pos_profile()
add_transactions()
add_vouchers()
def tearDown(self):
@classmethod
def tearDownClass(cls):
for bt in frappe.get_all("Bank Transaction"):
doc = frappe.get_doc("Bank Transaction", bt.name)
doc.cancel()
@@ -33,9 +35,6 @@ class TestBankTransaction(unittest.TestCase):
# Delete POS Profile
frappe.db.sql("delete from `tabPOS Profile`")
frappe.flags.test_bank_transactions_created = False
frappe.flags.test_payments_created = False
# This test checks if ERPNext is able to provide a linked payment for a bank transaction based on the amount of the bank transaction.
def test_linked_payments(self):
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="Re 95282925234 FE/000002917 AT171513000281183046 Conrad Electronic"))
@@ -44,8 +43,8 @@ class TestBankTransaction(unittest.TestCase):
# This test validates a simple reconciliation leading to the clearance of the bank transaction and the payment
def test_reconcile(self):
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="1512567 BG/000002918 OPSKATTUZWXXX AT776000000098709837 Herr G"))
payment = frappe.get_doc("Payment Entry", dict(party="Mr G", paid_amount=1200))
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="1512567 BG/000003025 OPSKATTUZWXXX AT776000000098709849 Herr G"))
payment = frappe.get_doc("Payment Entry", dict(party="Mr G", paid_amount=1700))
vouchers = json.dumps([{
"payment_doctype":"Payment Entry",
"payment_name":payment.name,
@@ -62,7 +61,6 @@ class TestBankTransaction(unittest.TestCase):
def test_debit_credit_output(self):
bank_transaction = frappe.get_doc("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'])
print(linked_payments)
self.assertTrue(linked_payments[0][3])
# Check error if already reconciled
@@ -116,10 +114,6 @@ def create_bank_account(bank_name="Citi Bank", account_name="_Test Bank - _TC"):
pass
def add_transactions():
if frappe.flags.test_bank_transactions_created:
return
frappe.set_user("Administrator")
create_bank_account()
doc = frappe.get_doc({
@@ -172,14 +166,8 @@ def add_transactions():
}).insert()
doc.submit()
frappe.flags.test_bank_transactions_created = True
def add_vouchers():
if frappe.flags.test_payments_created:
return
frappe.set_user("Administrator")
try:
frappe.get_doc({
"doctype": "Supplier",
@@ -272,13 +260,6 @@ def add_vouchers():
except frappe.DuplicateEntryError:
pass
si = create_sales_invoice(customer="Fayva", qty=1, rate=109080)
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank - _TC")
pe.reference_no = "Fayva Oct 18"
pe.reference_date = "2018-10-29"
pe.insert()
pe.submit()
mode_of_payment = frappe.get_doc({
"doctype": "Mode of Payment",
"name": "Cash"
@@ -291,14 +272,12 @@ def add_vouchers():
})
mode_of_payment.save()
si = create_sales_invoice(customer="Fayva", qty=1, rate=109080, do_not_submit=1)
si = create_sales_invoice(customer="Fayva", qty=1, rate=109080, do_not_save=1)
si.is_pos = 1
si.append("payments", {
"mode_of_payment": "Cash",
"account": "_Test Bank - _TC",
"amount": 109080
})
si.save()
si.insert()
si.submit()
frappe.flags.test_payments_created = True

View File

@@ -57,6 +57,7 @@ class CForm(Document):
total = sum([flt(d.grand_total) for d in self.get('invoices')])
frappe.db.set(self, 'total_invoiced_amount', total)
@frappe.whitelist()
def get_invoice_details(self, invoice_no):
""" Pull details from invoices for referrence """
if invoice_no:

View File

@@ -293,6 +293,11 @@ def validate_accounts(file_name):
accounts_dict = {}
for account in accounts:
accounts_dict.setdefault(account["account_name"], account)
if not hasattr(account, "parent_account"):
msg = _("Please make sure the file you are using has 'Parent Account' column present in the header.")
msg += "<br><br>"
msg += _("Alternatively, you can download the template and fill your data in.")
frappe.throw(msg, title=_("Parent Account Missing"))
if account["parent_account"] and accounts_dict.get(account["parent_account"]):
accounts_dict[account["parent_account"]]["is_group"] = 1

View File

@@ -50,6 +50,7 @@ class CostCenter(NestedSet):
frappe.throw(_("{0} is not a group node. Please select a group node as parent cost center").format(
frappe.bold(self.parent_cost_center)))
@frappe.whitelist()
def convert_group_to_ledger(self):
if self.check_if_child_exists():
frappe.throw(_("Cannot convert Cost Center to ledger as it has child nodes"))
@@ -60,6 +61,7 @@ class CostCenter(NestedSet):
self.save()
return 1
@frappe.whitelist()
def convert_ledger_to_group(self):
if cint(self.enable_distributed_cost_center):
frappe.throw(_("Cost Center with enabled distributed cost center can not be converted to group"))

View File

@@ -42,9 +42,9 @@ class TestDunning(unittest.TestCase):
['Sales - _TC', 0.0, 20.44]
])
for gle in gl_entries:
self.assertEquals(expected_values[gle.account][0], gle.account)
self.assertEquals(expected_values[gle.account][1], gle.debit)
self.assertEquals(expected_values[gle.account][2], gle.credit)
self.assertEqual(expected_values[gle.account][0], gle.account)
self.assertEqual(expected_values[gle.account][1], gle.debit)
self.assertEqual(expected_values[gle.account][2], gle.credit)
def test_payment_entry(self):
dunning = create_dunning()

View File

@@ -21,21 +21,17 @@ frappe.ui.form.on('Exchange Rate Revaluation', {
refresh: function(frm) {
if(frm.doc.docstatus==1) {
frappe.db.get_value("Journal Entry Account", {
'reference_type': 'Exchange Rate Revaluation',
'reference_name': frm.doc.name,
'docstatus': 1
}, "sum(debit) as sum", (r) =>{
let total_amt = 0;
frm.doc.accounts.forEach(d=> {
total_amt = total_amt + d['new_balance_in_base_currency'];
});
if(total_amt !== r.sum) {
frm.add_custom_button(__('Journal Entry'), function() {
return frm.events.make_jv(frm);
}, __('Create'));
frappe.call({
method: 'check_journal_entry_condition',
doc: frm.doc,
callback: function(r) {
if (r.message) {
frm.add_custom_button(__('Journal Entry'), function() {
return frm.events.make_jv(frm);
}, __('Create'));
}
}
}, 'Journal Entry');
});
}
},

View File

@@ -27,6 +27,24 @@ class ExchangeRateRevaluation(Document):
if not (self.company and self.posting_date):
frappe.throw(_("Please select Company and Posting Date to getting entries"))
@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")
total_amt = 0
for d in self.accounts:
total_amt = total_amt + d.new_balance_in_base_currency
if total_amt != total_debit:
return True
return False
@frappe.whitelist()
def get_accounts_data(self, account=None):
accounts = []
self.validate_mandatory()
@@ -95,6 +113,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

View File

@@ -12,6 +12,7 @@ from frappe.model.document import Document
class FiscalYearIncorrectDate(frappe.ValidationError): pass
class FiscalYear(Document):
@frappe.whitelist()
def set_as_default(self):
frappe.db.set_value("Global Defaults", None, "current_fiscal_year", self.name)
global_defaults = frappe.get_doc("Global Defaults")
@@ -54,7 +55,7 @@ class FiscalYear(Document):
def on_update(self):
check_duplicate_fiscal_year(self)
frappe.cache().delete_value("fiscal_years")
def on_trash(self):
global_defaults = frappe.get_doc("Global Defaults")
if global_defaults.current_fiscal_year == self.name:

View File

@@ -290,4 +290,8 @@ def rename_temporarily_named_docs(doctype):
oldname = doc.name
set_name_from_naming_options(frappe.get_meta(doctype).autoname, doc)
newname = doc.name
frappe.db.sql("""UPDATE `tab{}` SET name = %s, to_rename = 0 where name = %s""".format(doctype), (newname, oldname))
frappe.db.sql(
"UPDATE `tab{}` SET name = %s, to_rename = 0 where name = %s".format(doctype),
(newname, oldname),
auto_commit=True
)

View File

@@ -54,4 +54,4 @@ class TestGLEntry(unittest.TestCase):
self.assertTrue(all(new.name != old.name for new, old in zip(gl_entries, new_gl_entries)))
new_naming_series_current_value = frappe.db.sql("SELECT current from tabSeries where name = %s", naming_series)[0][0]
self.assertEquals(old_naming_series_current_value + 2, new_naming_series_current_value)
self.assertEqual(old_naming_series_current_value + 2, new_naming_series_current_value)

View File

@@ -125,6 +125,7 @@ class InvoiceDiscounting(AccountsController):
make_gl_entries(gl_entries, cancel=(self.docstatus == 2), update_outstanding='No')
@frappe.whitelist()
def create_disbursement_entry(self):
je = frappe.new_doc("Journal Entry")
je.voucher_type = 'Journal Entry'
@@ -174,6 +175,7 @@ class InvoiceDiscounting(AccountsController):
return je
@frappe.whitelist()
def close_loan(self):
je = frappe.new_doc("Journal Entry")
je.voucher_type = 'Journal Entry'

View File

@@ -327,18 +327,16 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({
},
setup_balance_formatter: function() {
var me = this;
$.each(["balance", "party_balance"], function(i, field) {
var df = frappe.meta.get_docfield("Journal Entry Account", field, me.frm.doc.name);
df.formatter = function(value, df, options, doc) {
var currency = frappe.meta.get_field_currency(df, doc);
var dr_or_cr = value ? ('<label>' + (value > 0.0 ? __("Dr") : __("Cr")) + '</label>') : "";
return "<div style='text-align: right'>"
+ ((value==null || value==="") ? "" : format_currency(Math.abs(value), currency))
+ " " + dr_or_cr
+ "</div>";
}
})
const formatter = function(value, df, options, doc) {
var currency = frappe.meta.get_field_currency(df, doc);
var dr_or_cr = value ? ('<label>' + (value > 0.0 ? __("Dr") : __("Cr")) + '</label>') : "";
return "<div style='text-align: right'>"
+ ((value==null || value==="") ? "" : format_currency(Math.abs(value), currency))
+ " " + dr_or_cr
+ "</div>";
};
this.frm.fields_dict.accounts.grid.update_docfield_property('balance', 'formatter', formatter);
this.frm.fields_dict.accounts.grid.update_docfield_property('party_balance', 'formatter', formatter);
},
reference_name: function(doc, cdt, cdn) {
@@ -431,15 +429,6 @@ cur_frm.cscript.validate = function(doc,cdt,cdn) {
cur_frm.cscript.update_totals(doc);
}
cur_frm.cscript.select_print_heading = function(doc,cdt,cdn){
if(doc.select_print_heading){
// print heading
cur_frm.pformat.print_heading = doc.select_print_heading;
}
else
cur_frm.pformat.print_heading = __("Journal Entry");
}
frappe.ui.form.on("Journal Entry Account", {
party: function(frm, cdt, cdn) {
var d = frappe.get_doc(cdt, cdn);
@@ -511,8 +500,11 @@ $.extend(erpnext.journal_entry, {
};
$.each(field_label_map, function (fieldname, label) {
var df = frappe.meta.get_docfield("Journal Entry Account", fieldname, frm.doc.name);
df.label = frm.doc.multi_currency ? (label + " in Account Currency") : label;
frm.fields_dict.accounts.grid.update_docfield_property(
fieldname,
'label',
frm.doc.multi_currency ? (label + " in Account Currency") : label
);
})
},

View File

@@ -564,6 +564,7 @@ class JournalEntry(AccountsController):
if gl_map:
make_gl_entries(gl_map, cancel=cancel, adv_adj=adv_adj, update_outstanding=update_outstanding)
@frappe.whitelist()
def get_balance(self):
if not self.get('accounts'):
msgprint(_("'Entries' cannot be empty"), raise_exception=True)
@@ -591,6 +592,7 @@ class JournalEntry(AccountsController):
self.validate_total_debit_and_credit()
@frappe.whitelist()
def get_outstanding_invoices(self):
self.set('accounts', [])
total = 0

View File

@@ -8,6 +8,7 @@ from frappe.utils import (flt, add_months)
from frappe.model.document import Document
class MonthlyDistribution(Document):
@frappe.whitelist()
def get_months(self):
month_list = ['January','February','March','April','May','June','July','August','September',
'October','November','December']

View File

@@ -167,6 +167,7 @@ class OpeningInvoiceCreationTool(Document):
return invoice
@frappe.whitelist()
def make_invoices(self):
self.validate_company()
invoices = self.get_invoices()

View File

@@ -6,10 +6,12 @@ from __future__ import unicode_literals
import frappe
import unittest
test_dependencies = ["Customer", "Supplier"]
from frappe.cache_manager import clear_doctype_cache
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
from erpnext.accounts.doctype.opening_invoice_creation_tool.opening_invoice_creation_tool import get_temporary_opening_account
test_dependencies = ["Customer", "Supplier"]
class TestOpeningInvoiceCreationTool(unittest.TestCase):
def setUp(self):
if not frappe.db.exists("Company", "_Test Opening Invoice Company"):
@@ -24,22 +26,25 @@ class TestOpeningInvoiceCreationTool(unittest.TestCase):
def test_opening_sales_invoice_creation(self):
property_setter = make_property_setter("Sales Invoice", "update_stock", "default", 1, "Check")
invoices = self.make_invoices(company="_Test Opening Invoice Company")
try:
invoices = self.make_invoices(company="_Test Opening Invoice Company")
self.assertEqual(len(invoices), 2)
expected_value = {
"keys": ["customer", "outstanding_amount", "status"],
0: ["_Test Customer", 300, "Overdue"],
1: ["_Test Customer 1", 250, "Overdue"],
}
self.check_expected_values(invoices, expected_value)
self.assertEqual(len(invoices), 2)
expected_value = {
"keys": ["customer", "outstanding_amount", "status"],
0: ["_Test Customer", 300, "Overdue"],
1: ["_Test Customer 1", 250, "Overdue"],
}
self.check_expected_values(invoices, expected_value)
si = frappe.get_doc("Sales Invoice", invoices[0])
si = frappe.get_doc("Sales Invoice", invoices[0])
# Check if update stock is not enabled
self.assertEqual(si.update_stock, 0)
# Check if update stock is not enabled
self.assertEqual(si.update_stock, 0)
property_setter.delete()
finally:
property_setter.delete()
clear_doctype_cache("Sales Invoice")
def check_expected_values(self, invoices, expected_value, invoice_type="Sales"):
doctype = "Sales Invoice" if invoice_type == "Sales" else "Purchase Invoice"
@@ -143,4 +148,4 @@ def make_customer(customer=None):
customer.insert(ignore_permissions=True)
return customer.name
else:
return frappe.db.exists("Customer", customer_name)
return frappe.db.exists("Customer", customer_name)

View File

@@ -1,87 +1,39 @@
{
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2014-08-29 16:02:39.740505",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"actions": [],
"creation": "2014-08-29 16:02:39.740505",
"doctype": "DocType",
"editable_grid": 1,
"field_order": [
"company",
"account"
],
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Company",
"length": 0,
"no_copy": 0,
"options": "Company",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
"fieldname": "company",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Company",
"options": "Company",
"reqd": 1
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "account",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Account",
"length": 0,
"no_copy": 0,
"options": "Account",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"fieldname": "account",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Account",
"options": "Account"
}
],
"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": "2016-07-11 03:28:03.348246",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Party Account",
"name_case": "",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_seen": 0
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2021-04-07 18:13:08.833822",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Party Account",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC"
}

View File

@@ -561,7 +561,7 @@ frappe.ui.form.on('Payment Entry', {
flt(frm.doc.received_amount) * flt(frm.doc.target_exchange_rate));
if(frm.doc.payment_type == "Pay")
frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.received_amount);
frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.received_amount, 1);
else
frm.events.set_unallocated_amount(frm);
@@ -582,7 +582,7 @@ frappe.ui.form.on('Payment Entry', {
}
if(frm.doc.payment_type == "Receive")
frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.paid_amount);
frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.paid_amount, 1);
else
frm.events.set_unallocated_amount(frm);
},
@@ -606,9 +606,9 @@ frappe.ui.form.on('Payment Entry', {
{fieldtype:"Float", label: __("Less Than Amount"), fieldname:"outstanding_amt_less_than"},
{fieldtype:"Section Break"},
{fieldtype:"Link", label:__("Cost Center"), fieldname:"cost_center", options:"Cost Center",
"get_query": function() {
return {
"filters": {"company": frm.doc.company}
"get_query": function() {
return {
"filters": {"company": frm.doc.company}
}
}
},
@@ -743,7 +743,7 @@ frappe.ui.form.on('Payment Entry', {
});
},
allocate_party_amount_against_ref_docs: function(frm, paid_amount) {
allocate_party_amount_against_ref_docs: function(frm, paid_amount, paid_amount_change) {
var total_positive_outstanding_including_order = 0;
var total_negative_outstanding = 0;
var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [],
@@ -800,22 +800,15 @@ frappe.ui.form.on('Payment Entry', {
//If allocate payment amount checkbox is unchecked, set zero to allocate amount
row.allocated_amount = 0;
} else if (frappe.flags.allocate_payment_amount != 0 && !row.allocated_amount) {
if (row.outstanding_amount > 0 && allocated_positive_outstanding > 0) {
if (row.outstanding_amount >= allocated_positive_outstanding) {
row.allocated_amount = allocated_positive_outstanding;
} else {
row.allocated_amount = row.outstanding_amount;
}
} else if (frappe.flags.allocate_payment_amount != 0 && (!row.allocated_amount || paid_amount_change)) {
if (row.outstanding_amount > 0 && allocated_positive_outstanding >= 0) {
row.allocated_amount = (row.outstanding_amount >= allocated_positive_outstanding) ?
allocated_positive_outstanding : row.outstanding_amount;
allocated_positive_outstanding -= flt(row.allocated_amount);
} else if (row.outstanding_amount < 0 && allocated_negative_outstanding) {
if (Math.abs(row.outstanding_amount) >= allocated_negative_outstanding) {
row.allocated_amount = -1*allocated_negative_outstanding;
} else {
row.allocated_amount = row.outstanding_amount;
};
} else if (row.outstanding_amount < 0 && allocated_negative_outstanding) {
row.allocated_amount = (Math.abs(row.outstanding_amount) >= allocated_negative_outstanding) ?
-1*allocated_negative_outstanding : row.outstanding_amount;
allocated_negative_outstanding -= Math.abs(flt(row.allocated_amount));
}
}

View File

@@ -31,10 +31,10 @@ class TestPaymentOrder(unittest.TestCase):
doc = create_payment_order_against_payment_entry(payment_entry, "Payment Entry")
reference_doc = doc.get("references")[0]
self.assertEquals(reference_doc.reference_name, payment_entry.name)
self.assertEquals(reference_doc.reference_doctype, "Payment Entry")
self.assertEquals(reference_doc.supplier, "_Test Supplier")
self.assertEquals(reference_doc.amount, 250)
self.assertEqual(reference_doc.reference_name, payment_entry.name)
self.assertEqual(reference_doc.reference_doctype, "Payment Entry")
self.assertEqual(reference_doc.supplier, "_Test Supplier")
self.assertEqual(reference_doc.amount, 250)
def create_payment_order_against_payment_entry(ref_doc, order_type):
payment_order = frappe.get_doc(dict(

View File

@@ -234,8 +234,9 @@ erpnext.accounts.PaymentReconciliationController = frappe.ui.form.Controller.ext
});
if (invoices) {
frappe.meta.get_docfield("Payment Reconciliation Payment", "invoice_number",
me.frm.doc.name).options = "\n" + invoices.join("\n");
this.frm.fields_dict.payments.grid.update_docfield_property(
'invoice_number', 'options', "\n" + invoices.join("\n")
);
$.each(me.frm.doc.payments || [], function(i, p) {
if(!in_list(invoices, cstr(p.invoice_number))) p.invoice_number = null;

View File

@@ -11,6 +11,7 @@ from erpnext.accounts.utils import (get_outstanding_invoices,
from erpnext.controllers.accounts_controller import get_advance_payment_entries
class PaymentReconciliation(Document):
@frappe.whitelist()
def get_unreconciled_entries(self):
self.get_nonreconciled_payment_entries()
self.get_invoice_entries()
@@ -113,7 +114,7 @@ class PaymentReconciliation(Document):
'party_type': self.party_type,
'voucher_type': voucher_type,
'account': self.receivable_payable_account
}, as_dict=1, debug=1)
}, as_dict=1)
def add_payment_entries(self, entries):
self.set('payments', [])
@@ -147,6 +148,7 @@ class PaymentReconciliation(Document):
ent.currency = e.get('currency')
ent.outstanding_amount = e.get('outstanding_amount')
@frappe.whitelist()
def reconcile(self, args):
for e in self.get('payments'):
e.invoice_type = None
@@ -197,6 +199,7 @@ class PaymentReconciliation(Document):
'difference_account': row.difference_account
})
@frappe.whitelist()
def get_difference_amount(self, child_row):
if child_row.get("reference_type") != 'Payment Entry': return

View File

@@ -20,10 +20,11 @@
"discount",
"section_break_9",
"payment_amount",
"outstanding",
"paid_amount",
"discounted_amount",
"column_break_3",
"outstanding",
"paid_amount"
"base_payment_amount"
],
"fields": [
{
@@ -78,7 +79,8 @@
"depends_on": "paid_amount",
"fieldname": "paid_amount",
"fieldtype": "Currency",
"label": "Paid Amount"
"label": "Paid Amount",
"options": "currency"
},
{
"fieldname": "column_break_3",
@@ -97,6 +99,7 @@
"fieldname": "outstanding",
"fieldtype": "Currency",
"label": "Outstanding",
"options": "currency",
"read_only": 1
},
{
@@ -145,12 +148,18 @@
{
"fieldname": "section_break_4",
"fieldtype": "Section Break"
},
{
"fieldname": "base_payment_amount",
"fieldtype": "Currency",
"label": "Payment Amount (Company Currency)",
"options": "Company:company:default_currency"
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2021-02-15 21:03:12.540546",
"modified": "2021-04-28 05:41:35.084233",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Schedule",

View File

@@ -22,7 +22,43 @@ frappe.ui.form.on('POS Closing Entry', {
});
if (frm.doc.docstatus === 0 && !frm.doc.amended_from) frm.set_value("period_end_date", frappe.datetime.now_datetime());
if (frm.doc.docstatus === 1) set_html_data(frm);
frappe.realtime.on('closing_process_complete', async function(data) {
await frm.reload_doc();
if (frm.doc.status == 'Failed' && frm.doc.error_message && data.user == frappe.session.user) {
frappe.msgprint({
title: __('POS Closing Failed'),
message: frm.doc.error_message,
indicator: 'orange',
clear: true
});
}
});
set_html_data(frm);
},
refresh: function(frm) {
if (frm.doc.docstatus == 1 && frm.doc.status == 'Failed') {
const issue = '<a id="jump_to_error" style="text-decoration: underline;">issue</a>';
frm.dashboard.set_headline(
__('POS Closing failed while running in a background process. You can resolve the {0} and retry the process again.', [issue]));
$('#jump_to_error').on('click', (e) => {
e.preventDefault();
frappe.utils.scroll_to(
cur_frm.get_field("error_message").$wrapper,
true,
30
);
});
frm.add_custom_button(__('Retry'), function () {
frm.call('retry', {}, () => {
frm.reload_doc();
});
});
}
},
pos_opening_entry(frm) {
@@ -61,48 +97,37 @@ frappe.ui.form.on('POS Closing Entry', {
refresh_fields(frm);
set_html_data(frm);
}
})
});
},
before_save: function(frm) {
frm.set_value("grand_total", 0);
frm.set_value("net_total", 0);
frm.set_value("total_quantity", 0);
frm.set_value("taxes", []);
for (let row of frm.doc.payment_reconciliation) {
row.expected_amount = 0;
}
for (let row of frm.doc.pos_transactions) {
frappe.db.get_doc("POS Invoice", row.pos_invoice).then(doc => {
frm.doc.grand_total += flt(doc.grand_total);
frm.doc.net_total += flt(doc.net_total);
frm.doc.total_quantity += flt(doc.total_qty);
refresh_payments(doc, frm);
refresh_taxes(doc, frm);
refresh_fields(frm);
set_html_data(frm);
});
}
}
});
cur_frm.cscript.before_pos_transactions_remove = function(doc, cdt, cdn) {
const removed_row = locals[cdt][cdn];
if (!removed_row.pos_invoice) return;
frappe.db.get_doc("POS Invoice", removed_row.pos_invoice).then(doc => {
cur_frm.doc.grand_total -= flt(doc.grand_total);
cur_frm.doc.net_total -= flt(doc.net_total);
cur_frm.doc.total_quantity -= flt(doc.total_qty);
refresh_payments(doc, cur_frm, 1);
refresh_taxes(doc, cur_frm, 1);
refresh_fields(cur_frm);
set_html_data(cur_frm);
});
}
frappe.ui.form.on('POS Invoice Reference', {
pos_invoice(frm, cdt, cdn) {
const added_row = locals[cdt][cdn];
if (!added_row.pos_invoice) return;
frappe.db.get_doc("POS Invoice", added_row.pos_invoice).then(doc => {
frm.doc.grand_total += flt(doc.grand_total);
frm.doc.net_total += flt(doc.net_total);
frm.doc.total_quantity += flt(doc.total_qty);
refresh_payments(doc, frm);
refresh_taxes(doc, frm);
refresh_fields(frm);
set_html_data(frm);
});
}
})
frappe.ui.form.on('POS Closing Entry Detail', {
closing_amount: (frm, cdt, cdn) => {
const row = locals[cdt][cdn];
frappe.model.set_value(cdt, cdn, "difference", flt(row.expected_amount - row.closing_amount))
frappe.model.set_value(cdt, cdn, "difference", flt(row.expected_amount - row.closing_amount));
}
})
@@ -126,28 +151,28 @@ function add_to_pos_transaction(d, frm) {
})
}
function refresh_payments(d, frm, remove) {
function refresh_payments(d, frm) {
d.payments.forEach(p => {
const payment = frm.doc.payment_reconciliation.find(pay => pay.mode_of_payment === p.mode_of_payment);
if (payment) {
if (!remove) payment.expected_amount += flt(p.amount);
else payment.expected_amount -= flt(p.amount);
payment.expected_amount += flt(p.amount);
payment.difference = payment.closing_amount - payment.expected_amount;
} else {
frm.add_child("payment_reconciliation", {
mode_of_payment: p.mode_of_payment,
opening_amount: 0,
expected_amount: p.amount
expected_amount: p.amount,
closing_amount: 0
})
}
})
}
function refresh_taxes(d, frm, remove) {
function refresh_taxes(d, frm) {
d.taxes.forEach(t => {
const tax = frm.doc.taxes.find(tx => tx.account_head === t.account_head && tx.rate === t.rate);
if (tax) {
if (!remove) tax.amount += flt(t.tax_amount);
else tax.amount -= flt(t.tax_amount);
tax.amount += flt(t.tax_amount);
} else {
frm.add_child("taxes", {
account_head: t.account_head,
@@ -177,11 +202,13 @@ function refresh_fields(frm) {
}
function set_html_data(frm) {
frappe.call({
method: "get_payment_reconciliation_details",
doc: frm.doc,
callback: (r) => {
frm.get_field("payment_reconciliation_details").$wrapper.html(r.message);
}
})
if (frm.doc.docstatus === 1 && frm.doc.status == 'Submitted') {
frappe.call({
method: "get_payment_reconciliation_details",
doc: frm.doc,
callback: (r) => {
frm.get_field("payment_reconciliation_details").$wrapper.html(r.message);
}
});
}
}

View File

@@ -30,6 +30,8 @@
"total_quantity",
"column_break_16",
"taxes",
"failure_description_section",
"error_message",
"section_break_14",
"amended_from"
],
@@ -195,7 +197,7 @@
"fieldtype": "Select",
"hidden": 1,
"label": "Status",
"options": "Draft\nSubmitted\nQueued\nCancelled",
"options": "Draft\nSubmitted\nQueued\nFailed\nCancelled",
"print_hide": 1,
"read_only": 1
},
@@ -203,6 +205,21 @@
"fieldname": "period_details_section",
"fieldtype": "Section Break",
"label": "Period Details"
},
{
"collapsible": 1,
"collapsible_depends_on": "error_message",
"depends_on": "error_message",
"fieldname": "failure_description_section",
"fieldtype": "Section Break",
"label": "Failure Description"
},
{
"depends_on": "error_message",
"fieldname": "error_message",
"fieldtype": "Small Text",
"label": "Error",
"read_only": 1
}
],
"is_submittable": 1,
@@ -212,7 +229,7 @@
"link_fieldname": "pos_closing_entry"
}
],
"modified": "2021-02-01 13:47:20.722104",
"modified": "2021-05-05 16:59:49.723261",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Closing Entry",

View File

@@ -16,33 +16,13 @@ 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_pos_closing()
self.validate_pos_invoices()
def validate_pos_closing(self):
user = frappe.db.sql("""
SELECT name FROM `tabPOS Closing Entry`
WHERE
user = %(user)s AND docstatus = 1 AND pos_profile = %(profile)s AND
(period_start_date between %(start)s and %(end)s OR period_end_date between %(start)s and %(end)s)
""", {
'user': self.user,
'profile': self.pos_profile,
'start': self.period_start_date,
'end': self.period_end_date
})
if user:
bold_already_exists = frappe.bold(_("already exists"))
bold_user = frappe.bold(self.user)
frappe.throw(_("POS Closing Entry {} against {} between selected period")
.format(bold_already_exists, bold_user), title=_("Invalid Period"))
def validate_pos_invoices(self):
invalid_rows = []
for d in self.pos_transactions:
invalid_row = {'idx': d.idx}
pos_invoice = frappe.db.get_values("POS Invoice", d.pos_invoice,
pos_invoice = frappe.db.get_values("POS Invoice", d.pos_invoice,
["consolidated_invoice", "pos_profile", "docstatus", "owner"], as_dict=1)[0]
if pos_invoice.consolidated_invoice:
invalid_row.setdefault('msg', []).append(_('POS Invoice is {}').format(frappe.bold("already consolidated")))
@@ -68,17 +48,22 @@ class POSClosingEntry(StatusUpdater):
frappe.throw(error_list, title=_("Invalid POS Invoices"), as_list=True)
@frappe.whitelist()
def get_payment_reconciliation_details(self):
currency = frappe.get_cached_value('Company', self.company, "default_currency")
return frappe.render_template("erpnext/accounts/doctype/pos_closing_entry/closing_voucher_details.html",
{"data": self, "currency": currency})
def on_submit(self):
consolidate_pos_invoices(closing_entry=self)
def on_cancel(self):
unconsolidate_pos_invoices(closing_entry=self)
@frappe.whitelist()
def retry(self):
consolidate_pos_invoices(closing_entry=self)
def update_opening_entry(self, for_cancel=False):
opening_entry = frappe.get_doc("POS Opening Entry", self.pos_opening_entry)
opening_entry.pos_closing_entry = self.name if not for_cancel else None
@@ -88,8 +73,8 @@ class POSClosingEntry(StatusUpdater):
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def get_cashiers(doctype, txt, searchfield, start, page_len, filters):
cashiers_list = frappe.get_all("POS Profile User", filters=filters, fields=['user'])
return [c['user'] for c in cashiers_list]
cashiers_list = frappe.get_all("POS Profile User", filters=filters, fields=['user'], as_list=1)
return [c for c in cashiers_list]
@frappe.whitelist()
def get_pos_invoices(start, end, pos_profile, user):

View File

@@ -8,6 +8,7 @@ frappe.listview_settings['POS Closing Entry'] = {
"Draft": "red",
"Submitted": "blue",
"Queued": "orange",
"Failed": "red",
"Cancelled": "red"
};

View File

@@ -5,12 +5,21 @@ from __future__ import unicode_literals
import frappe
import unittest
from frappe.utils import nowdate
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
from erpnext.accounts.doctype.pos_invoice.test_pos_invoice import create_pos_invoice
from erpnext.accounts.doctype.pos_closing_entry.pos_closing_entry import make_closing_entry_from_opening
from erpnext.accounts.doctype.pos_opening_entry.test_pos_opening_entry import create_opening_entry
from erpnext.accounts.doctype.pos_profile.test_pos_profile import make_pos_profile
class TestPOSClosingEntry(unittest.TestCase):
def setUp(self):
# Make stock available for POS Sales
make_stock_entry(target="_Test Warehouse - _TC", qty=2, basic_rate=100)
def tearDown(self):
frappe.set_user("Administrator")
frappe.db.sql("delete from `tabPOS Profile`")
def test_pos_closing_entry(self):
test_user, pos_profile = init_user_and_profile()
opening_entry = create_opening_entry(pos_profile, test_user.name)
@@ -41,9 +50,6 @@ class TestPOSClosingEntry(unittest.TestCase):
self.assertEqual(pcv_doc.total_quantity, 2)
self.assertEqual(pcv_doc.net_total, 6700)
frappe.set_user("Administrator")
frappe.db.sql("delete from `tabPOS Profile`")
def test_cancelling_of_pos_closing_entry(self):
test_user, pos_profile = init_user_and_profile()
opening_entry = create_opening_entry(pos_profile, test_user.name)
@@ -84,8 +90,6 @@ class TestPOSClosingEntry(unittest.TestCase):
self.assertEqual(si_doc.docstatus, 2)
self.assertEqual(pos_inv1.status, 'Paid')
frappe.set_user("Administrator")
frappe.db.sql("delete from `tabPOS Profile`")
def init_user_and_profile(**args):
user = 'test@example.com'
@@ -103,4 +107,4 @@ def init_user_and_profile(**args):
pos_profile.save()
return test_user, pos_profile
return test_user, pos_profile

View File

@@ -96,30 +96,45 @@ 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. {} has already been transacted into another POS Invoice. Please select valid serial no.")
.format(item.idx, bold_invalid_serial_nos), title=_("Item Unavailable"))
def validate_delivered_serial_nos(self, item):
serial_nos = get_serial_nos(item.serial_no)
delivered_serial_nos = frappe.db.get_list('Serial No', {
'item_code': item.item_code,
'name': ['in', serial_nos],
'sales_invoice': ['is', 'set']
}, pluck='name')
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_stock_availablility(self):
if self.is_return:
return
allow_negative_stock = frappe.db.get_value('Stock Settings', None, 'allow_negative_stock')
error_msg = []
allow_negative_stock = frappe.db.get_single_value('Stock Settings', 'allow_negative_stock')
for d in self.get('items'):
msg = ""
if d.serial_no:
filters = { "item_code": d.item_code, "warehouse": d.warehouse }
if d.batch_no:
filters["batch_no"] = d.batch_no
reserved_serial_nos = get_pos_reserved_serial_nos(filters)
serial_nos = get_serial_nos(d.serial_no)
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:
msg = (_("Row #{}: Serial No. {} has already been transacted into another POS Invoice. Please select valid serial no.")
.format(d.idx, bold_invalid_serial_nos))
elif invalid_serial_nos:
msg = (_("Row #{}: Serial Nos. {} has already been transacted into another POS Invoice. Please select valid serial no.")
.format(d.idx, bold_invalid_serial_nos))
self.validate_pos_reserved_serial_nos(d)
self.validate_delivered_serial_nos(d)
else:
if allow_negative_stock:
return
@@ -127,15 +142,11 @@ class POSInvoice(SalesInvoice):
available_stock = get_stock_availability(d.item_code, d.warehouse)
item_code, warehouse, qty = frappe.bold(d.item_code), frappe.bold(d.warehouse), frappe.bold(d.qty)
if flt(available_stock) <= 0:
msg = (_('Row #{}: Item Code: {} is not available under warehouse {}.').format(d.idx, item_code, warehouse))
frappe.throw(_('Row #{}: Item Code: {} is not available under warehouse {}.')
.format(d.idx, item_code, warehouse), title=_("Item Unavailable"))
elif flt(available_stock) < flt(d.qty):
msg = (_('Row #{}: Stock quantity not enough for Item Code: {} under warehouse {}. Available quantity {}.')
.format(d.idx, item_code, warehouse, qty))
if msg:
error_msg.append(msg)
if error_msg:
frappe.throw(error_msg, title=_("Item Unavailable"), as_list=True)
frappe.throw(_('Row #{}: Stock quantity not enough for Item Code: {} under warehouse {}. Available quantity {}.')
.format(d.idx, item_code, warehouse, available_stock), title=_("Item Unavailable"))
def validate_serialised_or_batched_item(self):
error_msg = []
@@ -202,9 +213,8 @@ class POSInvoice(SalesInvoice):
for d in self.get("items"):
is_stock_item = frappe.get_cached_value("Item", d.get("item_code"), "is_stock_item")
if not is_stock_item:
frappe.throw(_("Row #{}: Item {} is a non stock item. You can only include stock items in a POS Invoice. ").format(
d.idx, frappe.bold(d.item_code)
), title=_("Invalid Item"))
frappe.throw(_("Row #{}: Item {} is a non stock item. You can only include stock items in a POS Invoice. ")
.format(d.idx, frappe.bold(d.item_code)), title=_("Invalid Item"))
def validate_mode_of_payment(self):
if len(self.payments) == 0:
@@ -220,7 +230,7 @@ class POSInvoice(SalesInvoice):
base_grand_total = flt(self.base_rounded_total) or flt(self.base_grand_total)
if not flt(self.change_amount) and grand_total < flt(self.paid_amount):
self.change_amount = flt(self.paid_amount - grand_total + flt(self.write_off_amount))
self.base_change_amount = flt(self.base_paid_amount - base_grand_total + flt(self.base_write_off_amount))
self.base_change_amount = flt(self.base_paid_amount) - base_grand_total + flt(self.base_write_off_amount)
if flt(self.change_amount) and not self.account_for_change_amount:
frappe.msgprint(_("Please enter Account for Change Amount"), raise_exception=1)
@@ -354,6 +364,7 @@ class POSInvoice(SalesInvoice):
return profile
@frappe.whitelist()
def set_missing_values(self, for_validate=False):
profile = self.set_pos_fields(for_validate)
@@ -376,12 +387,20 @@ class POSInvoice(SalesInvoice):
"allow_print_before_pay": profile.get("allow_print_before_pay")
}
@frappe.whitelist()
def reset_mode_of_payments(self):
if self.pos_profile:
pos_profile = frappe.get_cached_doc('POS Profile', self.pos_profile)
update_multi_mode_option(self, pos_profile)
self.paid_amount = 0
def set_account_for_mode_of_payment(self):
self.payments = [d for d in self.payments if d.amount or d.base_amount or d.default]
for pay in self.payments:
if not pay.account:
pay.account = get_bank_cash_account(pay.mode_of_payment, self.company).get("account")
@frappe.whitelist()
def create_payment_request(self):
for pay in self.payments:
if pay.type == "Phone":
@@ -442,7 +461,17 @@ def get_stock_availability(item_code, warehouse):
order by posting_date desc, posting_time desc
limit 1""", (item_code, warehouse), as_dict=1)
pos_sales_qty = frappe.db.sql("""select sum(p_item.qty) as qty
pos_sales_qty = get_pos_reserved_qty(item_code, warehouse)
sle_qty = latest_sle[0].qty_after_transaction or 0 if latest_sle else 0
if sle_qty and pos_sales_qty:
return sle_qty - pos_sales_qty
else:
return sle_qty
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 p.consolidated_invoice is NULL
@@ -451,14 +480,8 @@ def get_stock_availability(item_code, warehouse):
and p_item.item_code = %s
and p_item.warehouse = %s
""", (item_code, warehouse), as_dict=1)
sle_qty = latest_sle[0].qty_after_transaction or 0 if latest_sle else 0
pos_sales_qty = pos_sales_qty[0].qty or 0 if pos_sales_qty else 0
if sle_qty and pos_sales_qty:
return sle_qty - pos_sales_qty
else:
return sle_qty
return reserved_qty[0].qty or 0 if reserved_qty else 0
@frappe.whitelist()
def make_sales_return(source_name, target_doc=None):

View File

@@ -9,8 +9,22 @@ from erpnext.accounts.doctype.pos_profile.test_pos_profile import make_pos_profi
from erpnext.accounts.doctype.pos_invoice.pos_invoice import make_sales_return
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
from erpnext.stock.doctype.item.test_item import make_item
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
class TestPOSInvoice(unittest.TestCase):
@classmethod
def setUpClass(cls):
make_stock_entry(target="_Test Warehouse - _TC", item_code="_Test Item", qty=800, basic_rate=100)
frappe.db.sql("delete from `tabTax Rule`")
def tearDown(self):
if frappe.session.user != "Administrator":
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)
def test_timestamp_change(self):
w = create_pos_invoice(do_not_save=1)
w.docstatus = 0
@@ -308,6 +322,34 @@ class TestPOSInvoice(unittest.TestCase):
self.assertRaises(frappe.ValidationError, pos2.insert)
def test_delivered_serialized_item_transaction(self):
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
se = make_serialized_item(company='_Test Company',
target_warehouse="Stores - _TC", cost_center='Main - _TC', expense_account='Cost of Goods Sold - _TC')
serial_nos = get_serial_nos(se.get("items")[0].serial_no)
si = create_sales_invoice(company='_Test Company', debit_to='Debtors - _TC',
account_for_change_amount='Cash - _TC', warehouse='Stores - _TC', income_account='Sales - _TC',
expense_account='Cost of Goods Sold - _TC', cost_center='Main - _TC',
item=se.get("items")[0].item_code, rate=1000, do_not_save=1)
si.get("items")[0].serial_no = serial_nos[0]
si.insert()
si.submit()
pos2 = create_pos_invoice(company='_Test Company', debit_to='Debtors - _TC',
account_for_change_amount='Cash - _TC', warehouse='Stores - _TC', income_account='Sales - _TC',
expense_account='Cost of Goods Sold - _TC', cost_center='Main - _TC',
item=se.get("items")[0].item_code, rate=1000, 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})
self.assertRaises(frappe.ValidationError, pos2.insert)
def test_loyalty_points(self):
from erpnext.accounts.doctype.loyalty_program.test_loyalty_program import create_records
from erpnext.accounts.doctype.loyalty_program.loyalty_program import get_loyalty_program_details_with_points
@@ -370,7 +412,6 @@ class TestPOSInvoice(unittest.TestCase):
pos_inv.load_from_db()
rounded_total = frappe.db.get_value("Sales Invoice", pos_inv.consolidated_invoice, "rounded_total")
self.assertEqual(rounded_total, 3470)
frappe.set_user("Administrator")
def test_merging_into_sales_invoice_with_discount_and_inclusive_tax(self):
from erpnext.accounts.doctype.pos_closing_entry.test_pos_closing_entry import init_user_and_profile
@@ -412,7 +453,6 @@ class TestPOSInvoice(unittest.TestCase):
pos_inv.load_from_db()
rounded_total = frappe.db.get_value("Sales Invoice", pos_inv.consolidated_invoice, "rounded_total")
self.assertEqual(rounded_total, 840)
frappe.set_user("Administrator")
def test_merging_with_validate_selling_price(self):
from erpnext.accounts.doctype.pos_closing_entry.test_pos_closing_entry import init_user_and_profile
@@ -421,10 +461,12 @@ 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)
make_purchase_receipt(item_code="_Test Item", warehouse="_Test Warehouse - _TC", qty=1, rate=300)
item = "Test Selling Price Validation"
make_item(item, {"is_stock_item": 1})
make_purchase_receipt(item_code=item, warehouse="_Test Warehouse - _TC", qty=1, rate=300)
frappe.db.sql("delete from `tabPOS Invoice`")
test_user, pos_profile = init_user_and_profile()
pos_inv = create_pos_invoice(rate=300, do_not_submit=1)
pos_inv = create_pos_invoice(item=item, rate=300, do_not_submit=1)
pos_inv.append('payments', {
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 300
})
@@ -438,7 +480,7 @@ class TestPOSInvoice(unittest.TestCase):
})
self.assertRaises(frappe.ValidationError, pos_inv.submit)
pos_inv2 = create_pos_invoice(rate=400, do_not_submit=1)
pos_inv2 = create_pos_invoice(item=item, rate=400, do_not_submit=1)
pos_inv2.append('payments', {
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 400
})
@@ -457,8 +499,6 @@ class TestPOSInvoice(unittest.TestCase):
pos_inv2.load_from_db()
rounded_total = frappe.db.get_value("Sales Invoice", pos_inv2.consolidated_invoice, "rounded_total")
self.assertEqual(rounded_total, 400)
frappe.set_user("Administrator")
frappe.db.set_value("Selling Settings", "Selling Settings", "validate_selling_price", 0)
def create_pos_invoice(**args):
args = frappe._dict(args)
@@ -508,4 +548,4 @@ def create_pos_invoice(**args):
else:
pos_inv.payment_schedule = []
return pos_inv
return pos_inv

View File

@@ -12,8 +12,8 @@ from frappe.utils.background_jobs import enqueue
from frappe.model.mapper import map_doc, map_child_doc
from frappe.utils.scheduler import is_scheduler_inactive
from frappe.core.page.background_jobs.background_jobs import get_info
from six import iteritems
import json
import six
class POSInvoiceMergeLog(Document):
def validate(self):
@@ -78,8 +78,11 @@ class POSInvoiceMergeLog(Document):
sales_invoice = self.merge_pos_invoice_into(sales_invoice, data)
sales_invoice.is_consolidated = 1
sales_invoice.set_posting_time = 1
sales_invoice.posting_date = getdate(self.posting_date)
sales_invoice.save()
sales_invoice.submit()
self.consolidated_invoice = sales_invoice.name
return sales_invoice.name
@@ -91,10 +94,13 @@ class POSInvoiceMergeLog(Document):
credit_note = self.merge_pos_invoice_into(credit_note, data)
credit_note.is_consolidated = 1
credit_note.set_posting_time = 1
credit_note.posting_date = getdate(self.posting_date)
# TODO: return could be against multiple sales invoice which could also have been consolidated?
# credit_note.return_against = self.consolidated_invoice
credit_note.save()
credit_note.submit()
self.consolidated_credit_note = credit_note.name
return credit_note.name
@@ -131,12 +137,14 @@ class POSInvoiceMergeLog(Document):
if t.account_head == tax.account_head and t.cost_center == tax.cost_center:
t.tax_amount = flt(t.tax_amount) + flt(tax.tax_amount_after_discount_amount)
t.base_tax_amount = flt(t.base_tax_amount) + flt(tax.base_tax_amount_after_discount_amount)
update_item_wise_tax_detail(t, tax)
found = True
if not found:
tax.charge_type = 'Actual'
tax.included_in_print_rate = 0
tax.tax_amount = tax.tax_amount_after_discount_amount
tax.base_tax_amount = tax.base_tax_amount_after_discount_amount
tax.item_wise_tax_detail = tax.item_wise_tax_detail
taxes.append(tax)
for payment in doc.get('payments'):
@@ -168,11 +176,9 @@ class POSInvoiceMergeLog(Document):
sales_invoice = frappe.new_doc('Sales Invoice')
sales_invoice.customer = self.customer
sales_invoice.is_pos = 1
# date can be pos closing date?
sales_invoice.posting_date = getdate(nowdate())
return sales_invoice
def update_pos_invoices(self, invoice_docs, sales_invoice='', credit_note=''):
for doc in invoice_docs:
doc.load_from_db()
@@ -187,6 +193,26 @@ class POSInvoiceMergeLog(Document):
si.flags.ignore_validate = True
si.cancel()
def update_item_wise_tax_detail(consolidate_tax_row, tax_row):
consolidated_tax_detail = json.loads(consolidate_tax_row.item_wise_tax_detail)
tax_row_detail = json.loads(tax_row.item_wise_tax_detail)
if not consolidated_tax_detail:
consolidated_tax_detail = {}
for item_code, tax_data in tax_row_detail.items():
if consolidated_tax_detail.get(item_code):
consolidated_tax_data = consolidated_tax_detail.get(item_code)
consolidated_tax_detail.update({
item_code: [consolidated_tax_data[0], consolidated_tax_data[1] + tax_data[1]]
})
else:
consolidated_tax_detail.update({
item_code: [tax_data[0], tax_data[1]]
})
consolidate_tax_row.item_wise_tax_detail = json.dumps(consolidated_tax_detail, separators=(',', ':'))
def get_all_unconsolidated_invoices():
filters = {
'consolidated_invoice': [ 'in', [ '', None ]],
@@ -208,13 +234,13 @@ def get_invoice_customer_map(pos_invoices):
return pos_invoice_customer_map
def consolidate_pos_invoices(pos_invoices=[], closing_entry={}):
invoices = pos_invoices or closing_entry.get('pos_transactions') or get_all_unconsolidated_invoices()
def consolidate_pos_invoices(pos_invoices=None, closing_entry=None):
invoices = pos_invoices or (closing_entry and closing_entry.get('pos_transactions')) or get_all_unconsolidated_invoices()
invoice_by_customer = get_invoice_customer_map(invoices)
if len(invoices) >= 5 and closing_entry:
if len(invoices) >= 10 and closing_entry:
closing_entry.set_status(update=True, status='Queued')
enqueue_job(create_merge_logs, invoice_by_customer, closing_entry)
enqueue_job(create_merge_logs, invoice_by_customer=invoice_by_customer, closing_entry=closing_entry)
else:
create_merge_logs(invoice_by_customer, closing_entry)
@@ -225,50 +251,83 @@ def unconsolidate_pos_invoices(closing_entry):
pluck='name'
)
if len(merge_logs) >= 5:
if len(merge_logs) >= 10:
closing_entry.set_status(update=True, status='Queued')
enqueue_job(cancel_merge_logs, merge_logs, closing_entry)
enqueue_job(cancel_merge_logs, merge_logs=merge_logs, closing_entry=closing_entry)
else:
cancel_merge_logs(merge_logs, closing_entry)
def create_merge_logs(invoice_by_customer, closing_entry={}):
for customer, invoices in iteritems(invoice_by_customer):
merge_log = frappe.new_doc('POS Invoice Merge Log')
merge_log.posting_date = getdate(nowdate())
merge_log.customer = customer
merge_log.pos_closing_entry = closing_entry.get('name', None)
def create_merge_logs(invoice_by_customer, closing_entry=None):
try:
for customer, invoices in six.iteritems(invoice_by_customer):
merge_log = frappe.new_doc('POS Invoice Merge Log')
merge_log.posting_date = getdate(closing_entry.get('posting_date')) if closing_entry else nowdate()
merge_log.customer = customer
merge_log.pos_closing_entry = closing_entry.get('name') if closing_entry else None
merge_log.set('pos_invoices', invoices)
merge_log.save(ignore_permissions=True)
merge_log.submit()
if closing_entry:
closing_entry.set_status(update=True, status='Submitted')
closing_entry.update_opening_entry()
merge_log.set('pos_invoices', invoices)
merge_log.save(ignore_permissions=True)
merge_log.submit()
def cancel_merge_logs(merge_logs, closing_entry={}):
for log in merge_logs:
merge_log = frappe.get_doc('POS Invoice Merge Log', log)
merge_log.flags.ignore_permissions = True
merge_log.cancel()
if closing_entry:
closing_entry.set_status(update=True, status='Submitted')
closing_entry.db_set('error_message', '')
closing_entry.update_opening_entry()
if closing_entry:
closing_entry.set_status(update=True, status='Cancelled')
closing_entry.update_opening_entry(for_cancel=True)
except Exception:
frappe.db.rollback()
message_log = frappe.message_log.pop()
error_message = safe_load_json(message_log)
def enqueue_job(job, invoice_by_customer, closing_entry):
if closing_entry:
closing_entry.set_status(update=True, status='Failed')
closing_entry.db_set('error_message', error_message)
raise
finally:
frappe.db.commit()
frappe.publish_realtime('closing_process_complete', {'user': frappe.session.user})
def cancel_merge_logs(merge_logs, closing_entry=None):
try:
for log in merge_logs:
merge_log = frappe.get_doc('POS Invoice Merge Log', log)
merge_log.flags.ignore_permissions = True
merge_log.cancel()
if closing_entry:
closing_entry.set_status(update=True, status='Cancelled')
closing_entry.db_set('error_message', '')
closing_entry.update_opening_entry(for_cancel=True)
except Exception:
frappe.db.rollback()
message_log = frappe.message_log.pop()
error_message = safe_load_json(message_log)
if closing_entry:
closing_entry.set_status(update=True, status='Submitted')
closing_entry.db_set('error_message', error_message)
raise
finally:
frappe.db.commit()
frappe.publish_realtime('closing_process_complete', {'user': frappe.session.user})
def enqueue_job(job, **kwargs):
check_scheduler_status()
closing_entry = kwargs.get('closing_entry') or {}
job_name = closing_entry.get("name")
if not job_already_enqueued(job_name):
enqueue(
job,
**kwargs,
queue="long",
timeout=10000,
event="processing_merge_logs",
job_name=job_name,
closing_entry=closing_entry,
invoice_by_customer=invoice_by_customer,
now=frappe.conf.developer_mode or frappe.flags.in_test
)
@@ -286,4 +345,14 @@ def check_scheduler_status():
def job_already_enqueued(job_name):
enqueued_jobs = [d.get("job_name") for d in get_info()]
if job_name in enqueued_jobs:
return True
return True
def safe_load_json(message):
JSONDecodeError = ValueError if six.PY2 else json.JSONDecodeError
try:
json_message = json.loads(message).get('message')
except JSONDecodeError:
json_message = message
return json_message

View File

@@ -5,6 +5,7 @@ from __future__ import unicode_literals
import frappe
import unittest
import json
from erpnext.accounts.doctype.pos_invoice.test_pos_invoice import create_pos_invoice
from erpnext.accounts.doctype.pos_invoice.pos_invoice import make_sales_return
from erpnext.accounts.doctype.pos_invoice_merge_log.pos_invoice_merge_log import consolidate_pos_invoices
@@ -14,85 +15,136 @@ class TestPOSInvoiceMergeLog(unittest.TestCase):
def test_consolidated_invoice_creation(self):
frappe.db.sql("delete from `tabPOS Invoice`")
test_user, pos_profile = init_user_and_profile()
try:
test_user, pos_profile = init_user_and_profile()
pos_inv = create_pos_invoice(rate=300, do_not_submit=1)
pos_inv.append('payments', {
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 300
})
pos_inv.submit()
pos_inv = create_pos_invoice(rate=300, do_not_submit=1)
pos_inv.append('payments', {
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 300
})
pos_inv.submit()
pos_inv2 = create_pos_invoice(rate=3200, do_not_submit=1)
pos_inv2.append('payments', {
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 3200
})
pos_inv2.submit()
pos_inv2 = create_pos_invoice(rate=3200, do_not_submit=1)
pos_inv2.append('payments', {
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 3200
})
pos_inv2.submit()
pos_inv3 = create_pos_invoice(customer="_Test Customer 2", rate=2300, do_not_submit=1)
pos_inv3.append('payments', {
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 2300
})
pos_inv3.submit()
pos_inv3 = create_pos_invoice(customer="_Test Customer 2", rate=2300, do_not_submit=1)
pos_inv3.append('payments', {
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 2300
})
pos_inv3.submit()
consolidate_pos_invoices()
consolidate_pos_invoices()
pos_inv.load_from_db()
self.assertTrue(frappe.db.exists("Sales Invoice", pos_inv.consolidated_invoice))
pos_inv.load_from_db()
self.assertTrue(frappe.db.exists("Sales Invoice", pos_inv.consolidated_invoice))
pos_inv3.load_from_db()
self.assertTrue(frappe.db.exists("Sales Invoice", pos_inv3.consolidated_invoice))
pos_inv3.load_from_db()
self.assertTrue(frappe.db.exists("Sales Invoice", pos_inv3.consolidated_invoice))
self.assertFalse(pos_inv.consolidated_invoice == pos_inv3.consolidated_invoice)
self.assertFalse(pos_inv.consolidated_invoice == pos_inv3.consolidated_invoice)
finally:
frappe.set_user("Administrator")
frappe.db.sql("delete from `tabPOS Profile`")
frappe.db.sql("delete from `tabPOS Invoice`")
frappe.set_user("Administrator")
frappe.db.sql("delete from `tabPOS Profile`")
frappe.db.sql("delete from `tabPOS Invoice`")
def test_consolidated_credit_note_creation(self):
frappe.db.sql("delete from `tabPOS Invoice`")
test_user, pos_profile = init_user_and_profile()
try:
test_user, pos_profile = init_user_and_profile()
pos_inv = create_pos_invoice(rate=300, do_not_submit=1)
pos_inv.append('payments', {
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 300
})
pos_inv.submit()
pos_inv = create_pos_invoice(rate=300, do_not_submit=1)
pos_inv.append('payments', {
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 300
})
pos_inv.submit()
pos_inv2 = create_pos_invoice(rate=3200, do_not_submit=1)
pos_inv2.append('payments', {
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 3200
})
pos_inv2.submit()
pos_inv2 = create_pos_invoice(rate=3200, do_not_submit=1)
pos_inv2.append('payments', {
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 3200
})
pos_inv2.submit()
pos_inv3 = create_pos_invoice(customer="_Test Customer 2", rate=2300, do_not_submit=1)
pos_inv3.append('payments', {
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 2300
})
pos_inv3.submit()
pos_inv3 = create_pos_invoice(customer="_Test Customer 2", rate=2300, do_not_submit=1)
pos_inv3.append('payments', {
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 2300
})
pos_inv3.submit()
pos_inv_cn = make_sales_return(pos_inv.name)
pos_inv_cn.set("payments", [])
pos_inv_cn.append('payments', {
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': -300
})
pos_inv_cn.paid_amount = -300
pos_inv_cn.submit()
pos_inv_cn = make_sales_return(pos_inv.name)
pos_inv_cn.set("payments", [])
pos_inv_cn.append('payments', {
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': -300
})
pos_inv_cn.paid_amount = -300
pos_inv_cn.submit()
consolidate_pos_invoices()
consolidate_pos_invoices()
pos_inv.load_from_db()
self.assertTrue(frappe.db.exists("Sales Invoice", pos_inv.consolidated_invoice))
pos_inv.load_from_db()
self.assertTrue(frappe.db.exists("Sales Invoice", pos_inv.consolidated_invoice))
pos_inv3.load_from_db()
self.assertTrue(frappe.db.exists("Sales Invoice", pos_inv3.consolidated_invoice))
pos_inv3.load_from_db()
self.assertTrue(frappe.db.exists("Sales Invoice", pos_inv3.consolidated_invoice))
pos_inv_cn.load_from_db()
self.assertTrue(frappe.db.exists("Sales Invoice", pos_inv_cn.consolidated_invoice))
self.assertTrue(frappe.db.get_value("Sales Invoice", pos_inv_cn.consolidated_invoice, "is_return"))
pos_inv_cn.load_from_db()
self.assertTrue(frappe.db.exists("Sales Invoice", pos_inv_cn.consolidated_invoice))
self.assertTrue(frappe.db.get_value("Sales Invoice", pos_inv_cn.consolidated_invoice, "is_return"))
frappe.set_user("Administrator")
frappe.db.sql("delete from `tabPOS Profile`")
finally:
frappe.set_user("Administrator")
frappe.db.sql("delete from `tabPOS Profile`")
frappe.db.sql("delete from `tabPOS Invoice`")
def test_consolidated_invoice_item_taxes(self):
frappe.db.sql("delete from `tabPOS Invoice`")
try:
inv = create_pos_invoice(qty=1, rate=100, do_not_save=True)
inv.append("taxes", {
"account_head": "_Test Account VAT - _TC",
"charge_type": "On Net Total",
"cost_center": "_Test Cost Center - _TC",
"description": "VAT",
"doctype": "Sales Taxes and Charges",
"rate": 9
})
inv.insert()
inv.submit()
inv2 = create_pos_invoice(qty=1, rate=100, do_not_save=True)
inv2.get('items')[0].item_code = '_Test Item 2'
inv2.append("taxes", {
"account_head": "_Test Account VAT - _TC",
"charge_type": "On Net Total",
"cost_center": "_Test Cost Center - _TC",
"description": "VAT",
"doctype": "Sales Taxes and Charges",
"rate": 5
})
inv2.insert()
inv2.submit()
consolidate_pos_invoices()
inv.load_from_db()
consolidated_invoice = frappe.get_doc('Sales Invoice', inv.consolidated_invoice)
item_wise_tax_detail = json.loads(consolidated_invoice.get('taxes')[0].item_wise_tax_detail)
tax_rate, amount = item_wise_tax_detail.get('_Test Item')
self.assertEqual(tax_rate, 9)
self.assertEqual(amount, 9)
tax_rate2, amount2 = item_wise_tax_detail.get('_Test Item 2')
self.assertEqual(tax_rate2, 5)
self.assertEqual(amount2, 5)
finally:
frappe.set_user("Administrator")
frappe.db.sql("delete from `tabPOS Profile`")
frappe.db.sql("delete from `tabPOS Invoice`")

View File

@@ -0,0 +1,37 @@
{
"actions": [],
"creation": "2021-04-19 14:56:06.652327",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"field",
"fieldname"
],
"fields": [
{
"fieldname": "fieldname",
"fieldtype": "Data",
"hidden": 1,
"label": "Fieldname"
},
{
"fieldname": "field",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Field"
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2021-04-21 11:12:54.632093",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Search Fields",
"owner": "Administrator",
"permissions": [],
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

View File

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
# import frappe
from frappe.model.document import Document
class POSSearchFields(Document):
pass

View File

@@ -1,9 +1,17 @@
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
let search_fields_datatypes = ['Data', 'Link', 'Dynamic Link', 'Long Text', 'Select', 'Small Text', 'Text', 'Text Editor'];
let do_not_include_fields = ["naming_series", "item_code", "item_name", "stock_uom", "hub_sync_id", "asset_naming_series",
"default_material_request_type", "valuation_method", "warranty_period", "weight_uom", "batch_number_series",
"serial_no_series", "purchase_uom", "customs_tariff_number", "sales_uom", "deferred_revenue_account",
"deferred_expense_account", "quality_inspection_template", "route", "slideshow", "website_image_alt", "thumbnail",
"web_long_description", "hub_sync_id"]
frappe.ui.form.on('POS Settings', {
onload: function(frm) {
frm.trigger("get_invoice_fields");
frm.trigger("add_search_options");
},
get_invoice_fields: function(frm) {
@@ -16,8 +24,43 @@ frappe.ui.form.on('POS Settings', {
}
});
frappe.meta.get_docfield("POS Field", "fieldname", frm.doc.name).options = [""].concat(fields);
frm.fields_dict.invoice_fields.grid.update_docfield_property(
'fieldname', 'options', [""].concat(fields)
);
});
},
add_search_options: function(frm) {
frappe.model.with_doctype("Item", () => {
var fields = $.map(frappe.get_doc("DocType", "Item").fields, function(d) {
if (search_fields_datatypes.includes(d.fieldtype) && !(do_not_include_fields.includes(d.fieldname))) {
return [d.label];
} else {
return null;
}
});
fields.unshift('');
frm.fields_dict.pos_search_fields.grid.update_docfield_property('field', 'options', fields);
});
}
});
frappe.ui.form.on("POS Search Fields", {
field: function(frm, doctype, name) {
var doc = frappe.get_doc(doctype, name);
var df = $.map(frappe.get_doc("DocType", "Item").fields, function(d) {
if (doc.field == d.label && search_fields_datatypes.includes(d.fieldtype)) {
return d;
} else {
return null;
}
})[0];
doc.fieldname = df.fieldname;
frm.refresh_field("fields");
}
});

View File

@@ -5,7 +5,8 @@
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"invoice_fields"
"invoice_fields",
"pos_search_fields"
],
"fields": [
{
@@ -13,11 +14,17 @@
"fieldtype": "Table",
"label": "POS Field",
"options": "POS Field"
},
{
"fieldname": "pos_search_fields",
"fieldtype": "Table",
"label": "POS Search Fields",
"options": "POS Search Fields"
}
],
"issingle": 1,
"links": [],
"modified": "2020-06-01 15:46:41.478928",
"modified": "2021-04-19 14:56:24.465218",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Settings",

View File

@@ -99,7 +99,7 @@ class TestPricingRule(unittest.TestCase):
args.item_code = "_Test Item 2"
details = get_item_details(args)
self.assertEquals(details.get("discount_percentage"), 15)
self.assertEqual(details.get("discount_percentage"), 15)
def test_pricing_rule_for_margin(self):
from erpnext.stock.get_item_details import get_item_details
@@ -145,8 +145,8 @@ class TestPricingRule(unittest.TestCase):
"name": None
})
details = get_item_details(args)
self.assertEquals(details.get("margin_type"), "Percentage")
self.assertEquals(details.get("margin_rate_or_amount"), 10)
self.assertEqual(details.get("margin_type"), "Percentage")
self.assertEqual(details.get("margin_rate_or_amount"), 10)
def test_mixed_conditions_for_item_group(self):
for item in ["Mixed Cond Item 1", "Mixed Cond Item 2"]:
@@ -192,7 +192,7 @@ class TestPricingRule(unittest.TestCase):
"name": None
})
details = get_item_details(args)
self.assertEquals(details.get("discount_percentage"), 10)
self.assertEqual(details.get("discount_percentage"), 10)
def test_pricing_rule_for_variants(self):
from erpnext.stock.get_item_details import get_item_details
@@ -322,11 +322,11 @@ class TestPricingRule(unittest.TestCase):
si.insert(ignore_permissions=True)
item = si.items[0]
self.assertEquals(item.margin_rate_or_amount, 10)
self.assertEquals(item.rate_with_margin, 1100)
self.assertEqual(item.margin_rate_or_amount, 10)
self.assertEqual(item.rate_with_margin, 1100)
self.assertEqual(item.discount_percentage, 10)
self.assertEquals(item.discount_amount, 110)
self.assertEquals(item.rate, 990)
self.assertEqual(item.discount_amount, 110)
self.assertEqual(item.rate, 990)
def test_pricing_rule_with_margin_and_discount_amount(self):
frappe.delete_doc_if_exists('Pricing Rule', '_Test Pricing Rule')
@@ -338,10 +338,10 @@ class TestPricingRule(unittest.TestCase):
si.insert(ignore_permissions=True)
item = si.items[0]
self.assertEquals(item.margin_rate_or_amount, 10)
self.assertEquals(item.rate_with_margin, 1100)
self.assertEquals(item.discount_amount, 110)
self.assertEquals(item.rate, 990)
self.assertEqual(item.margin_rate_or_amount, 10)
self.assertEqual(item.rate_with_margin, 1100)
self.assertEqual(item.discount_amount, 110)
self.assertEqual(item.rate, 990)
def test_pricing_rule_for_product_discount_on_same_item(self):
frappe.delete_doc_if_exists('Pricing Rule', '_Test Pricing Rule')
@@ -458,21 +458,21 @@ class TestPricingRule(unittest.TestCase):
si.items[0].price_list_rate = 1000
si.submit()
item = si.items[0]
self.assertEquals(item.rate, 100)
self.assertEqual(item.rate, 100)
# Correct Customer and Incorrect is_return value
si = create_sales_invoice(do_not_submit=True, customer="_Test Customer 1", is_return=1, qty=-1)
si.items[0].price_list_rate = 1000
si.submit()
item = si.items[0]
self.assertEquals(item.rate, 100)
self.assertEqual(item.rate, 100)
# Correct Customer and correct is_return value
si = create_sales_invoice(do_not_submit=True, customer="_Test Customer 1", is_return=0)
si.items[0].price_list_rate = 1000
si.submit()
item = si.items[0]
self.assertEquals(item.rate, 900)
self.assertEqual(item.rate, 900)
def test_multiple_pricing_rules(self):
make_pricing_rule(discount_percentage=20, selling=1, priority=1, apply_multiple_pricing_rules=1,
@@ -545,11 +545,11 @@ class TestPricingRule(unittest.TestCase):
apply_on="Transaction", free_item="Water Flask 1", free_qty=1, free_item_rate=10)
si = create_sales_invoice(qty=5, do_not_submit=True)
self.assertEquals(len(si.items), 2)
self.assertEquals(si.items[1].rate, 10)
self.assertEqual(len(si.items), 2)
self.assertEqual(si.items[1].rate, 10)
si1 = create_sales_invoice(qty=2, do_not_submit=True)
self.assertEquals(len(si1.items), 1)
self.assertEqual(len(si1.items), 1)
for doc in [si, si1]:
doc.delete()

View File

@@ -173,7 +173,7 @@ def _get_tree_conditions(args, parenttype, table, allow_blank=True):
if parenttype in ["Customer Group", "Item Group", "Territory"]:
parent_field = "parent_{0}".format(frappe.scrub(parenttype))
root_name = frappe.db.get_list(parenttype,
{"is_group": 1, parent_field: ("is", "not set")}, "name", as_list=1)
{"is_group": 1, parent_field: ("is", "not set")}, "name", as_list=1, ignore_permissions=True)
if root_name and root_name[0][0]:
parent_groups.append(root_name[0][0])
@@ -471,7 +471,7 @@ def apply_pricing_rule_on_transaction(doc):
if not d.get(pr_field): continue
if d.validate_applied_rule and doc.get(field) < d.get(pr_field):
if d.validate_applied_rule and doc.get(field) is not None and doc.get(field) < d.get(pr_field):
frappe.msgprint(_("User has not applied rule on the invoice {0}")
.format(doc.name))
else:

View File

@@ -19,7 +19,7 @@
</tr>
</thead>
<tbody>
{% for row in data %}
{% for row in data %}
<tr>
{% if(row.posting_date) %}
<td>{{ frappe.format(row.posting_date, 'Date') }}</td>
@@ -38,30 +38,30 @@
{% endif %}
</td>
<td style="text-align: right">
{{ frappe.utils.fmt_money(row.debit, filters.presentation_currency) }}</td>
{{ frappe.utils.fmt_money(row.debit, currency=filters.presentation_currency) }}</td>
<td style="text-align: right">
{{ frappe.utils.fmt_money(row.credit, filters.presentation_currency) }}</td>
{{ frappe.utils.fmt_money(row.credit, currency=filters.presentation_currency) }}</td>
{% else %}
<td></td>
<td></td>
<td><b>{{ frappe.format(row.account, {fieldtype: "Link"}) or "&nbsp;" }}</b></td>
<td style="text-align: right">
{{ row.account and frappe.utils.fmt_money(row.debit, filters.presentation_currency) }}
{{ row.account and frappe.utils.fmt_money(row.debit, currency=filters.presentation_currency) }}
</td>
<td style="text-align: right">
{{ row.account and frappe.utils.fmt_money(row.credit, filters.presentation_currency) }}
{{ row.account and frappe.utils.fmt_money(row.credit, currency=filters.presentation_currency) }}
</td>
{% endif %}
<td style="text-align: right">
{{ frappe.utils.fmt_money(row.balance, filters.presentation_currency) }}
{{ frappe.utils.fmt_money(row.balance, currency=filters.presentation_currency) }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<br><br>
{% if aging %}
<h3 class="text-center">{{ _("Ageing Report Based On ") }} {{ aging.ageing_based_on }}</h3>
{% if ageing %}
<h3 class="text-center">{{ _("Ageing Report Based On ") }} {{ ageing.ageing_based_on }}</h3>
<h5 class="text-center">
{{ _("Up to " ) }} {{ frappe.format(filters.to_date, 'Date')}}
</h5>
@@ -78,10 +78,10 @@
</thead>
<tbody>
<tr>
<td>{{ aging.range1 }}</td>
<td>{{ aging.range2 }}</td>
<td>{{ aging.range3 }}</td>
<td>{{ aging.range4 }}</td>
<td>{{ frappe.utils.fmt_money(ageing.range1, currency=filters.presentation_currency) }}</td>
<td>{{ frappe.utils.fmt_money(ageing.range2, currency=filters.presentation_currency) }}</td>
<td>{{ frappe.utils.fmt_money(ageing.range3, currency=filters.presentation_currency) }}</td>
<td>{{ frappe.utils.fmt_money(ageing.range4, currency=filters.presentation_currency) }}</td>
</tr>
</tbody>
</table>

View File

@@ -4,10 +4,12 @@
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.model.document import Document
from erpnext.accounts.report.general_ledger.general_ledger import execute as get_soa
from erpnext.accounts.report.accounts_receivable_summary.accounts_receivable_summary import execute as get_ageing
from frappe.core.doctype.communication.email import make
from erpnext import get_company_currency
from erpnext.accounts.party import get_party_account_currency
from frappe.utils.print_format import report_to_pdf
from frappe.utils.pdf import get_pdf
@@ -29,7 +31,7 @@ class ProcessStatementOfAccounts(Document):
validate_template(self.body)
if not self.customers:
frappe.throw(frappe._('Customers not selected.'))
frappe.throw(_('Customers not selected.'))
if self.enable_auto_email:
self.to_date = self.start_date
@@ -38,7 +40,7 @@ class ProcessStatementOfAccounts(Document):
def get_report_pdf(doc, consolidated=True):
statement_dict = {}
aging = ''
ageing = ''
base_template_path = "frappe/www/printview.html"
template_path = "erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.html"
@@ -54,26 +56,30 @@ def get_report_pdf(doc, consolidated=True):
'range4': 120,
'customer': entry.customer
})
col1, aging = get_ageing(ageing_filters)
aging[0]['ageing_based_on'] = doc.ageing_based_on
col1, ageing = get_ageing(ageing_filters)
if ageing:
ageing[0]['ageing_based_on'] = doc.ageing_based_on
tax_id = frappe.get_doc('Customer', entry.customer).tax_id
presentation_currency = get_party_account_currency('Customer', entry.customer, doc.company) \
or doc.currency or get_company_currency(doc.company)
filters= frappe._dict({
'from_date': doc.from_date,
'to_date': doc.to_date,
'company': doc.company,
'finance_book': doc.finance_book if doc.finance_book else None,
"account": doc.account if doc.account else None,
'account': doc.account if doc.account else None,
'party_type': 'Customer',
'party': [entry.customer],
'presentation_currency': presentation_currency,
'group_by': doc.group_by,
'currency': doc.currency,
'cost_center': [cc.cost_center_name for cc in doc.cost_center],
'project': [p.project_name for p in doc.project],
'show_opening_entries': 0,
'include_default_book_entries': 0,
'show_cancelled_entries': 1,
'tax_id': tax_id if tax_id else None
})
col, res = get_soa(filters)
@@ -83,11 +89,14 @@ def get_report_pdf(doc, consolidated=True):
if len(res) == 3:
continue
html = frappe.render_template(template_path, \
{"filters": filters, "data": res, "aging": aging[0] if doc.include_ageing else None})
{"filters": filters, "data": res, "ageing": ageing[0] if (doc.include_ageing and ageing) else None})
html = frappe.render_template(base_template_path, {"body": html, \
"css": get_print_style(), "title": "Statement For " + entry.customer})
statement_dict[entry.customer] = html
if not bool(statement_dict):
return False
elif consolidated:
@@ -167,7 +176,7 @@ def fetch_customers(customer_collection, collection_name, primary_mandatory):
if customer_collection == 'Sales Person':
customers = get_customers_based_on_sales_person(collection_name)
if not bool(customers):
frappe.throw('No Customers found with selected options.')
frappe.throw(_('No Customers found with selected options.'))
else:
if customer_collection == 'Sales Partner':
customers = frappe.get_list('Customer', fields=['name', 'email_id'], \
@@ -199,14 +208,14 @@ def get_customer_emails(customer_name, primary_mandatory, billing_and_primary=Tr
if len(billing_email) == 0 or (billing_email[0][0] is None):
if billing_and_primary:
frappe.throw('No billing email found for customer: '+ customer_name)
frappe.throw(_("No billing email found for customer: {0}").format(customer_name))
else:
return ''
if billing_and_primary:
primary_email = frappe.get_value('Customer', customer_name, 'email_id')
if primary_email is None and int(primary_mandatory):
frappe.throw('No primary email found for customer: '+ customer_name)
frappe.throw(_("No primary email found for customer: {0}").format(customer_name))
return [primary_email or '', billing_email[0][0]]
else:
return billing_email[0][0] or ''

View File

@@ -9,7 +9,7 @@ from frappe.utils import cstr
from frappe.model.naming import make_autoname
from frappe.model.document import Document
pricing_rule_fields = ['apply_on', 'mixed_conditions', 'is_cumulative', 'other_item_code', 'other_item_group'
pricing_rule_fields = ['apply_on', 'mixed_conditions', 'is_cumulative', 'other_item_code', 'other_item_group',
'apply_rule_on_other', 'other_brand', 'selling', 'buying', 'applicable_for', 'valid_from',
'valid_upto', 'customer', 'customer_group', 'territory', 'sales_partner', 'campaign', 'supplier',
'supplier_group', 'company', 'currency', 'apply_multiple_pricing_rules']
@@ -111,4 +111,4 @@ def get_args_for_pricing_rule(doc):
for d in pricing_rule_fields:
args[d] = doc.get(d)
return args
return args

View File

@@ -496,15 +496,6 @@ cur_frm.fields_dict['items'].grid.get_field('project').get_query = function(doc,
}
}
cur_frm.cscript.select_print_heading = function(doc,cdt,cdn){
if(doc.select_print_heading){
// print heading
cur_frm.pformat.print_heading = doc.select_print_heading;
}
else
cur_frm.pformat.print_heading = __("Purchase Invoice");
}
frappe.ui.form.on("Purchase Invoice", {
setup: function(frm) {
frm.custom_make_buttons = {
@@ -523,6 +514,28 @@ frappe.ui.form.on("Purchase Invoice", {
}
},
refresh: function(frm) {
frm.events.add_custom_buttons(frm);
},
add_custom_buttons: function(frm) {
if (frm.doc.per_received < 100) {
frm.add_custom_button(__('Purchase Receipt'), () => {
frm.events.make_purchase_receipt(frm);
}, __('Create'));
}
if (frm.doc.docstatus == 1 && frm.doc.per_received > 0) {
frm.add_custom_button(__('Purchase Receipt'), () => {
frappe.route_options = {
'purchase_invoice': frm.doc.name
}
frappe.set_route("List", "Purchase Receipt", "List")
}, __('View'));
}
},
onload: function(frm) {
if(frm.doc.__onload && frm.is_new()) {
if(frm.doc.supplier) {
@@ -548,5 +561,13 @@ frappe.ui.form.on("Purchase Invoice", {
update_stock: function(frm) {
hide_fields(frm.doc);
frm.fields_dict.items.grid.toggle_reqd("item_code", frm.doc.update_stock? true: false);
},
make_purchase_receipt: function(frm) {
frappe.model.open_mapped_doc({
method: "erpnext.accounts.doctype.purchase_invoice.purchase_invoice.make_purchase_receipt",
frm: frm,
freeze_message: __("Creating Purchase Receipt ...")
})
}
})

View File

@@ -127,7 +127,6 @@
"write_off_cost_center",
"advances_section",
"allocate_advances_automatically",
"adjust_advance_taxes",
"get_advances",
"advances",
"payment_schedule_section",
@@ -164,7 +163,8 @@
"to_date",
"column_break_114",
"auto_repeat",
"update_auto_repeat_reference"
"update_auto_repeat_reference",
"per_received"
],
"fields": [
{
@@ -1326,13 +1326,6 @@
"label": "Project",
"options": "Project"
},
{
"default": "0",
"description": "Taxes paid while advance payment will be adjusted against this invoice",
"fieldname": "adjust_advance_taxes",
"fieldtype": "Check",
"label": "Adjust Advance Taxes"
},
{
"depends_on": "eval:doc.is_internal_supplier",
"description": "Unrealized Profit / Loss account for intra-company transfers",
@@ -1372,13 +1365,22 @@
"print_hide": 1,
"print_width": "50px",
"width": "50px"
},
{
"fieldname": "per_received",
"fieldtype": "Percent",
"hidden": 1,
"label": "Per Received",
"no_copy": 1,
"print_hide": 1,
"read_only": 1
}
],
"icon": "fa fa-file-text",
"idx": 204,
"is_submittable": 1,
"links": [],
"modified": "2021-03-09 21:15:30.422084",
"modified": "2021-04-30 22:45:58.334107",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice",

View File

@@ -1207,3 +1207,41 @@ def make_inter_company_sales_invoice(source_name, target_doc=None):
def on_doctype_update():
frappe.db.add_index("Purchase Invoice", ["supplier", "is_return", "return_against"])
@frappe.whitelist()
def make_purchase_receipt(source_name, target_doc=None):
def update_item(obj, target, source_parent):
target.qty = flt(obj.qty) - flt(obj.received_qty)
target.received_qty = flt(obj.qty) - flt(obj.received_qty)
target.stock_qty = (flt(obj.qty) - flt(obj.received_qty)) * flt(obj.conversion_factor)
target.amount = (flt(obj.qty) - flt(obj.received_qty)) * flt(obj.rate)
target.base_amount = (flt(obj.qty) - flt(obj.received_qty)) * \
flt(obj.rate) * flt(source_parent.conversion_rate)
doc = get_mapped_doc("Purchase Invoice", source_name, {
"Purchase Invoice": {
"doctype": "Purchase Receipt",
"validation": {
"docstatus": ["=", 1],
}
},
"Purchase Invoice Item": {
"doctype": "Purchase Receipt Item",
"field_map": {
"name": "purchase_invoice_item",
"parent": "purchase_invoice",
"bom": "bom",
"purchase_order": "purchase_order",
"po_detail": "purchase_order_item",
"material_request": "material_request",
"material_request_item": "material_request_item"
},
"postprocess": update_item,
"condition": lambda doc: abs(doc.received_qty) < abs(doc.qty)
},
"Purchase Taxes and Charges": {
"doctype": "Purchase Taxes and Charges"
}
}, target_doc)
return doc

View File

@@ -397,7 +397,7 @@ class TestPurchaseInvoice(unittest.TestCase):
pi.update({
"payment_schedule": get_payment_terms("_Test Payment Term Template",
pi.posting_date, pi.grand_total)
pi.posting_date, pi.grand_total, pi.base_grand_total)
})
pi.save()
@@ -898,7 +898,7 @@ class TestPurchaseInvoice(unittest.TestCase):
acc_settings.submit_journal_entries = 1
acc_settings.save()
item = create_item("_Test Item for Deferred Accounting")
item = create_item("_Test Item for Deferred Accounting", is_purchase_item=True)
item.enable_deferred_expense = 1
item.deferred_expense_account = deferred_account
item.save()

View File

@@ -607,6 +607,7 @@
"oldfieldname": "purchase_order",
"oldfieldtype": "Link",
"options": "Purchase Order",
"print_hide": 1,
"read_only": 1,
"search_index": 1
},
@@ -853,7 +854,7 @@
"idx": 1,
"istable": 1,
"links": [],
"modified": "2021-02-23 00:59:52.614805",
"modified": "2021-03-30 09:02:39.256602",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice Item",

View File

@@ -1,9 +1,6 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
// print heading
cur_frm.pformat.print_heading = 'Invoice';
{% include 'erpnext/selling/sales_common.js' %};
frappe.provide("erpnext.accounts");
@@ -359,11 +356,11 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
},
items_on_form_rendered: function() {
erpnext.setup_serial_no();
erpnext.setup_serial_or_batch_no();
},
packed_items_on_form_rendered: function(doc, grid_row) {
erpnext.setup_serial_no();
erpnext.setup_serial_or_batch_no();
},
make_sales_return: function() {
@@ -916,7 +913,7 @@ frappe.ui.form.on('Sales Invoice Timesheet', {
},
callback: function(r, rt) {
if(r.message){
data = r.message;
let data = r.message;
frappe.model.set_value(cdt, cdn, "billing_hours", data.billing_hours);
frappe.model.set_value(cdt, cdn, "billing_amount", data.billing_amount);
frappe.model.set_value(cdt, cdn, "timesheet_detail", data.timesheet_detail);

View File

@@ -118,6 +118,7 @@
"in_words",
"total_advance",
"outstanding_amount",
"disable_rounded_total",
"advances_section",
"allocate_advances_automatically",
"get_advances",
@@ -1109,6 +1110,7 @@
"reqd": 1
},
{
"depends_on": "eval:!doc.disable_rounded_total",
"fieldname": "base_rounding_adjustment",
"fieldtype": "Currency",
"hide_days": 1,
@@ -1120,6 +1122,7 @@
"read_only": 1
},
{
"depends_on": "eval:!doc.disable_rounded_total",
"fieldname": "base_rounded_total",
"fieldtype": "Currency",
"hide_days": 1,
@@ -1168,6 +1171,7 @@
"reqd": 1
},
{
"depends_on": "eval:!doc.disable_rounded_total",
"fieldname": "rounding_adjustment",
"fieldtype": "Currency",
"hide_days": 1,
@@ -1180,6 +1184,7 @@
},
{
"bold": 1,
"depends_on": "eval:!doc.disable_rounded_total",
"fieldname": "rounded_total",
"fieldtype": "Currency",
"hide_days": 1,
@@ -1945,6 +1950,13 @@
"fieldtype": "Link",
"label": "Set Target Warehouse",
"options": "Warehouse"
},
{
"default": "0",
"depends_on": "grand_total",
"fieldname": "disable_rounded_total",
"fieldtype": "Check",
"label": "Disable Rounded Total"
}
],
"icon": "fa fa-file-text",
@@ -1957,7 +1969,7 @@
"link_fieldname": "consolidated_invoice"
}
],
"modified": "2021-03-31 15:42:26.261540",
"modified": "2021-04-15 23:57:58.766651",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",

View File

@@ -46,7 +46,6 @@ class SalesInvoice(SellingController):
'target_parent_dt': 'Sales Order',
'target_parent_field': 'per_billed',
'source_field': 'amount',
'join_field': 'so_detail',
'percent_join_field': 'sales_order',
'status_field': 'billing_status',
'keyword': 'Billed',
@@ -77,7 +76,7 @@ class SalesInvoice(SellingController):
if not self.is_pos:
self.so_dn_required()
self.set_tax_withholding()
self.validate_proj_cust()
@@ -276,7 +275,7 @@ class SalesInvoice(SellingController):
pluck="pos_closing_entry"
)
if pos_closing_entry:
msg = _("To cancel a {} you need to cancel the POS Closing Entry {}. ").format(
msg = _("To cancel a {} you need to cancel the POS Closing Entry {}.").format(
frappe.bold("Consolidated Sales Invoice"),
get_link_to_form("POS Closing Entry", pos_closing_entry[0])
)
@@ -394,6 +393,7 @@ class SalesInvoice(SellingController):
if validate_against_credit_limit:
check_credit_limit(self.customer, self.company, bypass_credit_limit_check_at_sales_order)
@frappe.whitelist()
def set_missing_values(self, for_validate=False):
pos = self.set_pos_fields(for_validate)
@@ -548,12 +548,12 @@ class SalesInvoice(SellingController):
frappe.throw(_("Debit To is required"), title=_("Account Missing"))
if account.report_type != "Balance Sheet":
msg = _("Please ensure {} account is a Balance Sheet account. ").format(frappe.bold("Debit To"))
msg = _("Please ensure {} account is a Balance Sheet account.").format(frappe.bold("Debit To")) + " "
msg += _("You can change the parent account to a Balance Sheet account or select a different account.")
frappe.throw(msg, title=_("Invalid Account"))
if self.customer and account.account_type != "Receivable":
msg = _("Please ensure {} account is a Receivable account. ").format(frappe.bold("Debit To"))
msg = _("Please ensure {} account is a Receivable account.").format(frappe.bold("Debit To")) + " "
msg += _("Change the account type to Receivable or select a different account.")
frappe.throw(msg, title=_("Invalid Account"))
@@ -733,6 +733,7 @@ class SalesInvoice(SellingController):
else:
self.calculate_billing_amount_for_timesheet()
@frappe.whitelist()
def add_timesheet_data(self):
self.set('timesheets', [])
if self.project:
@@ -1110,7 +1111,7 @@ class SalesInvoice(SellingController):
if not item.serial_no:
continue
for serial_no in item.serial_no.split("\n"):
for serial_no in get_serial_nos(item.serial_no):
if serial_no and frappe.db.get_value('Serial No', serial_no, 'item_code') == item.item_code:
frappe.db.set_value('Serial No', serial_no, 'sales_invoice', invoice)
@@ -1290,6 +1291,7 @@ class SalesInvoice(SellingController):
break
# Healthcare
@frappe.whitelist()
def set_healthcare_services(self, checked_values):
self.set("items", [])
from erpnext.stock.get_item_details import get_item_details
@@ -1753,15 +1755,10 @@ def update_pr_items(doc, sales_item_map, purchase_item_map, parent_child_map, wa
item.purchase_order = parent_child_map.get(sales_item_map.get(item.delivery_note_item))
def get_delivery_note_details(internal_reference):
so_item_map = {}
si_item_details = frappe.get_all('Delivery Note Item', fields=['name', 'so_detail'],
filters={'parent': internal_reference})
for d in si_item_details:
so_item_map.setdefault(d.name, d.so_detail)
return so_item_map
return {d.name: d.so_detail for d in si_item_details if d.so_detail}
def get_sales_invoice_details(internal_reference):
dn_item_map = {}

View File

@@ -1802,6 +1802,15 @@ class TestSalesInvoice(unittest.TestCase):
si.selling_price_list = "_Test Price List Rest of the World"
si.update_stock = 1
si.items[0].target_warehouse = 'Work In Progress - TCP1'
# Add stock to stores for succesful stock transfer
make_stock_entry(
target="Stores - TCP1",
company = "_Test Company with perpetual inventory",
qty=1,
basic_rate=100
)
add_taxes(si)
si.save()
@@ -1870,7 +1879,17 @@ class TestSalesInvoice(unittest.TestCase):
def test_einvoice_submission_without_irn(self):
# init
frappe.db.set_value('E Invoice Settings', 'E Invoice Settings', 'enable', 1)
einvoice_settings = frappe.get_doc('E Invoice Settings')
einvoice_settings.enable = 1
einvoice_settings.applicable_from = nowdate()
einvoice_settings.append('credentials', {
'company': '_Test Company',
'gstin': '27AAECE4835E1ZR',
'username': 'test',
'password': 'test'
})
einvoice_settings.save()
country = frappe.flags.country
frappe.flags.country = 'India'
@@ -1881,7 +1900,8 @@ class TestSalesInvoice(unittest.TestCase):
si.submit()
# reset
frappe.db.set_value('E Invoice Settings', 'E Invoice Settings', 'enable', 0)
einvoice_settings = frappe.get_doc('E Invoice Settings')
einvoice_settings.enable = 0
frappe.flags.country = country
def test_einvoice_json(self):
@@ -2272,4 +2292,4 @@ def add_taxes(doc):
"cost_center": "Main - TCP1",
"description": "Excise Duty",
"rate": 12
})
})

View File

@@ -46,5 +46,5 @@ def validate_disabled(doc):
frappe.throw(_("Disabled template must not be default template"))
def validate_for_tax_category(doc):
if frappe.db.exists(doc.doctype, {"company": doc.company, "tax_category": doc.tax_category, "disabled": 0}):
if frappe.db.exists(doc.doctype, {"company": doc.company, "tax_category": doc.tax_category, "disabled": 0, "name": ["!=", doc.name]}):
frappe.throw(_("A template with tax category {0} already exists. Only one template is allowed with each tax category").format(frappe.bold(doc.tax_category)))

View File

@@ -36,6 +36,7 @@
"additional_discount_percentage",
"additional_discount_amount",
"sb_3",
"submit_invoice",
"invoices",
"accounting_dimensions_section",
"cost_center",
@@ -45,9 +46,7 @@
{
"allow_on_submit": 1,
"fieldname": "cb_1",
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1
"fieldtype": "Column Break"
},
{
"fieldname": "status",
@@ -55,97 +54,73 @@
"label": "Status",
"no_copy": 1,
"options": "\nTrialling\nActive\nPast Due Date\nCancelled\nUnpaid\nCompleted",
"read_only": 1,
"show_days": 1,
"show_seconds": 1
"read_only": 1
},
{
"fieldname": "subscription_period",
"fieldtype": "Section Break",
"label": "Subscription Period",
"show_days": 1,
"show_seconds": 1
"label": "Subscription Period"
},
{
"fieldname": "cancelation_date",
"fieldtype": "Date",
"label": "Cancelation Date",
"read_only": 1,
"show_days": 1,
"show_seconds": 1
"read_only": 1
},
{
"allow_on_submit": 1,
"fieldname": "trial_period_start",
"fieldtype": "Date",
"label": "Trial Period Start Date",
"set_only_once": 1,
"show_days": 1,
"show_seconds": 1
"set_only_once": 1
},
{
"depends_on": "eval:doc.trial_period_start",
"fieldname": "trial_period_end",
"fieldtype": "Date",
"label": "Trial Period End Date",
"set_only_once": 1,
"show_days": 1,
"show_seconds": 1
"set_only_once": 1
},
{
"fieldname": "column_break_11",
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1
"fieldtype": "Column Break"
},
{
"fieldname": "current_invoice_start",
"fieldtype": "Date",
"label": "Current Invoice Start Date",
"read_only": 1,
"show_days": 1,
"show_seconds": 1
"read_only": 1
},
{
"fieldname": "current_invoice_end",
"fieldtype": "Date",
"label": "Current Invoice End Date",
"read_only": 1,
"show_days": 1,
"show_seconds": 1
"read_only": 1
},
{
"default": "0",
"description": "Number of days that the subscriber has to pay invoices generated by this subscription",
"fieldname": "days_until_due",
"fieldtype": "Int",
"label": "Days Until Due",
"show_days": 1,
"show_seconds": 1
"label": "Days Until Due"
},
{
"default": "0",
"fieldname": "cancel_at_period_end",
"fieldtype": "Check",
"label": "Cancel At End Of Period",
"show_days": 1,
"show_seconds": 1
"label": "Cancel At End Of Period"
},
{
"default": "0",
"fieldname": "generate_invoice_at_period_start",
"fieldtype": "Check",
"label": "Generate Invoice At Beginning Of Period",
"show_days": 1,
"show_seconds": 1
"label": "Generate Invoice At Beginning Of Period"
},
{
"allow_on_submit": 1,
"fieldname": "sb_4",
"fieldtype": "Section Break",
"label": "Plans",
"show_days": 1,
"show_seconds": 1
"label": "Plans"
},
{
"allow_on_submit": 1,
@@ -153,84 +128,62 @@
"fieldtype": "Table",
"label": "Plans",
"options": "Subscription Plan Detail",
"reqd": 1,
"show_days": 1,
"show_seconds": 1
"reqd": 1
},
{
"depends_on": "eval:['Customer', 'Supplier'].includes(doc.party_type)",
"fieldname": "sb_1",
"fieldtype": "Section Break",
"label": "Taxes",
"show_days": 1,
"show_seconds": 1
"label": "Taxes"
},
{
"fieldname": "sb_2",
"fieldtype": "Section Break",
"label": "Discounts",
"show_days": 1,
"show_seconds": 1
"label": "Discounts"
},
{
"fieldname": "apply_additional_discount",
"fieldtype": "Select",
"label": "Apply Additional Discount On",
"options": "\nGrand Total\nNet Total",
"show_days": 1,
"show_seconds": 1
"options": "\nGrand Total\nNet Total"
},
{
"fieldname": "cb_2",
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1
"fieldtype": "Column Break"
},
{
"fieldname": "additional_discount_percentage",
"fieldtype": "Percent",
"label": "Additional DIscount Percentage",
"show_days": 1,
"show_seconds": 1
"label": "Additional DIscount Percentage"
},
{
"collapsible": 1,
"fieldname": "additional_discount_amount",
"fieldtype": "Currency",
"label": "Additional DIscount Amount",
"show_days": 1,
"show_seconds": 1
"label": "Additional DIscount Amount"
},
{
"depends_on": "eval:doc.invoices",
"fieldname": "sb_3",
"fieldtype": "Section Break",
"label": "Invoices",
"show_days": 1,
"show_seconds": 1
"label": "Invoices"
},
{
"collapsible": 1,
"fieldname": "invoices",
"fieldtype": "Table",
"label": "Invoices",
"options": "Subscription Invoice",
"show_days": 1,
"show_seconds": 1
"options": "Subscription Invoice"
},
{
"collapsible": 1,
"fieldname": "accounting_dimensions_section",
"fieldtype": "Section Break",
"label": "Accounting Dimensions",
"show_days": 1,
"show_seconds": 1
"label": "Accounting Dimensions"
},
{
"fieldname": "dimension_col_break",
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1
"fieldtype": "Column Break"
},
{
"fieldname": "party_type",
@@ -238,9 +191,7 @@
"label": "Party Type",
"options": "DocType",
"reqd": 1,
"set_only_once": 1,
"show_days": 1,
"show_seconds": 1
"set_only_once": 1
},
{
"fieldname": "party",
@@ -249,27 +200,21 @@
"label": "Party",
"options": "party_type",
"reqd": 1,
"set_only_once": 1,
"show_days": 1,
"show_seconds": 1
"set_only_once": 1
},
{
"depends_on": "eval:doc.party_type === 'Customer'",
"fieldname": "sales_tax_template",
"fieldtype": "Link",
"label": "Sales Taxes and Charges Template",
"options": "Sales Taxes and Charges Template",
"show_days": 1,
"show_seconds": 1
"options": "Sales Taxes and Charges Template"
},
{
"depends_on": "eval:doc.party_type === 'Supplier'",
"fieldname": "purchase_tax_template",
"fieldtype": "Link",
"label": "Purchase Taxes and Charges Template",
"options": "Purchase Taxes and Charges Template",
"show_days": 1,
"show_seconds": 1
"options": "Purchase Taxes and Charges Template"
},
{
"default": "0",
@@ -277,55 +222,49 @@
"fieldname": "follow_calendar_months",
"fieldtype": "Check",
"label": "Follow Calendar Months",
"set_only_once": 1,
"show_days": 1,
"show_seconds": 1
"set_only_once": 1
},
{
"default": "0",
"description": "New invoices will be generated as per schedule even if current invoices are unpaid or past due date",
"fieldname": "generate_new_invoices_past_due_date",
"fieldtype": "Check",
"label": "Generate New Invoices Past Due Date",
"show_days": 1,
"show_seconds": 1
"label": "Generate New Invoices Past Due Date"
},
{
"fieldname": "end_date",
"fieldtype": "Date",
"label": "Subscription End Date",
"set_only_once": 1,
"show_days": 1,
"show_seconds": 1
"set_only_once": 1
},
{
"fieldname": "start_date",
"fieldtype": "Date",
"label": "Subscription Start Date",
"set_only_once": 1,
"show_days": 1,
"show_seconds": 1
"set_only_once": 1
},
{
"fieldname": "cost_center",
"fieldtype": "Link",
"label": "Cost Center",
"options": "Cost Center",
"show_days": 1,
"show_seconds": 1
"options": "Cost Center"
},
{
"fieldname": "company",
"fieldtype": "Link",
"label": "Company",
"options": "Company",
"show_days": 1,
"show_seconds": 1
"options": "Company"
},
{
"default": "1",
"fieldname": "submit_invoice",
"fieldtype": "Check",
"label": "Submit Invoice Automatically"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-02-09 15:44:20.024789",
"modified": "2021-04-19 15:24:27.550797",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Subscription",

View File

@@ -276,7 +276,7 @@ class Subscription(Document):
frappe.throw(_('Subscription End Date is mandatory to follow calendar months'))
if billing_info[0]['billing_interval'] != 'Month':
frappe.throw('Billing Interval in Subscription Plan must be Month to follow calendar months')
frappe.throw(_('Billing Interval in Subscription Plan must be Month to follow calendar months'))
def after_insert(self):
# todo: deal with users who collect prepayments. Maybe a new Subscription Invoice doctype?
@@ -383,7 +383,9 @@ class Subscription(Document):
invoice.flags.ignore_mandatory = True
invoice.save()
invoice.submit()
if self.submit_invoice:
invoice.submit()
return invoice

View File

@@ -14,10 +14,15 @@ test_records = frappe.get_test_records('Tax Rule')
from six import iteritems
class TestTaxRule(unittest.TestCase):
def setUp(self):
@classmethod
def setUpClass(cls):
frappe.db.set_value("Shopping Cart Settings", None, "enabled", 0)
@classmethod
def tearDownClass(cls):
frappe.db.sql("delete from `tabTax Rule`")
def tearDown(self):
def setUp(self):
frappe.db.sql("delete from `tabTax Rule`")
def test_conflict(self):

View File

@@ -21,7 +21,10 @@ def get_party_details(inv):
else:
party_type = 'Supplier'
party = inv.supplier
if not party:
frappe.throw(_("Please select {0} first").format(party_type))
return party_type, party
def get_party_tax_withholding_details(inv, tax_withholding_category=None):
@@ -251,7 +254,7 @@ def get_tds_amount(ldc, parties, inv, tax_details, fiscal_year_details, tax_dedu
threshold = tax_details.get('threshold', 0)
cumulative_threshold = tax_details.get('cumulative_threshold', 0)
if ((threshold and supp_credit_amt >= threshold) or (cumulative_threshold and supp_credit_amt >= cumulative_threshold)):
if ((threshold and inv.net_total >= threshold) or (cumulative_threshold and supp_credit_amt >= cumulative_threshold)):
if ldc and is_valid_certificate(
ldc.valid_from, ldc.valid_upto,
inv.posting_date, tax_deducted,
@@ -324,7 +327,7 @@ def get_tds_amount_from_ldc(ldc, parties, fiscal_year, pan_no, tax_details, post
net_total, ldc.certificate_limit
):
tds_amount = get_ltds_amount(net_total, limit_consumed, ldc.certificate_limit, ldc.rate, tax_details)
return tds_amount
def get_debit_note_amount(suppliers, fiscal_year_details, company=None):

View File

@@ -87,50 +87,6 @@ class TestTaxWithholdingCategory(unittest.TestCase):
for d in invoices:
d.cancel()
def test_single_threshold_tds_with_previous_vouchers(self):
invoices = []
frappe.db.set_value("Supplier", "Test TDS Supplier2", "tax_withholding_category", "Single Threshold TDS")
pi = create_purchase_invoice(supplier="Test TDS Supplier2")
pi.submit()
invoices.append(pi)
pi = create_purchase_invoice(supplier="Test TDS Supplier2")
pi.submit()
invoices.append(pi)
self.assertEqual(pi.taxes_and_charges_deducted, 2000)
self.assertEqual(pi.grand_total, 8000)
# delete invoices to avoid clashing
for d in invoices:
d.cancel()
def test_single_threshold_tds_with_previous_vouchers_and_no_tds(self):
invoices = []
doc = create_supplier(supplier_name = "Test TDS Supplier ABC",
tax_withholding_category="Single Threshold TDS")
supplier = doc.name
pi = create_purchase_invoice(supplier=supplier)
pi.submit()
invoices.append(pi)
# TDS not applied
pi = create_purchase_invoice(supplier=supplier, do_not_apply_tds=True)
pi.submit()
invoices.append(pi)
pi = create_purchase_invoice(supplier=supplier)
pi.submit()
invoices.append(pi)
self.assertEqual(pi.taxes_and_charges_deducted, 2000)
self.assertEqual(pi.grand_total, 8000)
# delete invoices to avoid clashing
for d in invoices:
d.cancel()
def test_cumulative_threshold_tcs(self):
frappe.db.set_value("Customer", "Test TCS Customer", "tax_withholding_category", "Cumulative Threshold TCS")
invoices = []
@@ -177,7 +133,7 @@ def cancel_invoices():
for d in purchase_invoices:
frappe.get_doc('Purchase Invoice', d).cancel()
for d in sales_invoices:
frappe.get_doc('Sales Invoice', d).cancel()
@@ -229,7 +185,8 @@ def create_sales_invoice(**args):
'qty': args.qty or 1,
'rate': args.rate or 10000,
'cost_center': 'Main - _TC',
'expense_account': 'Cost of Goods Sold - _TC'
'expense_account': 'Cost of Goods Sold - _TC',
'warehouse': args.warehouse or '_Test Warehouse - _TC'
}]
})
@@ -353,4 +310,4 @@ def create_tax_with_holding_category():
'company': '_Test Company',
'account': 'TDS - _TC'
}]
}).insert()
}).insert()

View File

@@ -18,7 +18,8 @@ def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True, upd
gl_map = process_gl_map(gl_map, merge_entries)
if gl_map and len(gl_map) > 1:
save_entries(gl_map, adv_adj, update_outstanding, from_repost)
else:
# Post GL Map proccess there may no be any GL Entries
elif gl_map:
frappe.throw(_("Incorrect number of General Ledger Entries found. You might have selected a wrong Account in the transaction."))
else:
make_reverse_gl_entries(gl_map, adv_adj=adv_adj, update_outstanding=update_outstanding)
@@ -170,7 +171,7 @@ def round_off_debit_credit(gl_map):
else:
allowance = .5
if abs(debit_credit_diff) >= allowance:
if abs(debit_credit_diff) > allowance:
frappe.throw(_("Debit and Credit not equal for {0} #{1}. Difference is {2}.")
.format(gl_map[0].voucher_type, gl_map[0].voucher_no, debit_credit_diff))

View File

@@ -1,5 +1,6 @@
{
"attach_print": 0,
"channel": "Email",
"condition": "doc.auto_created",
"creation": "2018-04-25 14:19:05.440361",
"days_in_advance": 0,

View File

@@ -364,7 +364,7 @@ class ReceivablePayableReport(object):
payment_terms_details = frappe.db.sql("""
select
si.name, si.party_account_currency, si.currency, si.conversion_rate,
ps.due_date, ps.payment_amount, ps.description, ps.paid_amount, ps.discounted_amount
ps.due_date, ps.payment_term, ps.payment_amount, ps.description, ps.paid_amount, ps.discounted_amount
from `tab{0}` si, `tabPayment Schedule` ps
where
si.name = ps.parent and
@@ -394,7 +394,7 @@ class ReceivablePayableReport(object):
"due_date": d.due_date,
"invoiced": invoiced,
"invoice_grand_total": row.invoiced,
"payment_term": d.description,
"payment_term": d.description or d.payment_term,
"paid": d.paid_amount + d.discounted_amount,
"credit_note": 0.0,
"outstanding": invoiced - d.paid_amount - d.discounted_amount

View File

@@ -5,7 +5,8 @@ from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import flt, cint
from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data)
from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data,
get_filtered_list_for_consolidated_report)
def execute(filters=None):
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
@@ -132,6 +133,10 @@ def get_report_summary(period_list, asset, liability, equity, provisional_profit
if filters.get('accumulated_values'):
period_list = [period_list[-1]]
# from consolidated financial statement
if filters.get('accumulated_in_group_company'):
period_list = get_filtered_list_for_consolidated_report(filters, period_list)
for period in period_list:
key = period if consolidated else period.key
if asset:

View File

@@ -0,0 +1,29 @@
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
/* eslint-disable */
frappe.query_reports['Billed Items To Be Received'] = {
'filters': [
{
'label': __('Company'),
'fieldname': 'company',
'fieldtype': 'Link',
'options': 'Company',
'reqd': 1,
'default': frappe.defaults.get_default('Company')
},
{
'label': __('As on Date'),
'fieldname': 'posting_date',
'fieldtype': 'Date',
'reqd': 1,
'default': get_today()
},
{
'label': __('Purchase Invoice'),
'fieldname': 'purchase_invoice',
'fieldtype': 'Link',
'options': 'Purchase Invoice'
}
]
};

View File

@@ -0,0 +1,39 @@
{
"add_total_row": 0,
"columns": [],
"creation": "2021-03-30 09:35:38.683028",
"disable_prepared_report": 0,
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"filters": [],
"idx": 0,
"is_standard": "Yes",
"modified": "2021-03-31 08:48:30.944429",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Billed Items To Be Received",
"owner": "Administrator",
"prepared_report": 0,
"query": "",
"ref_doctype": "Purchase Invoice",
"report_name": "Billed Items To Be Received",
"report_type": "Script Report",
"roles": [
{
"role": "Accounts User"
},
{
"role": "Purchase User"
},
{
"role": "Accounts Manager"
},
{
"role": "Auditor"
},
{
"role": "Stock User"
}
]
}

View File

@@ -0,0 +1,107 @@
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe import _
def execute(filters=None):
data = get_data(filters) or []
columns = get_columns()
return columns, data
def get_data(report_filters):
filters = get_report_filters(report_filters)
fields = get_report_fields()
return frappe.get_all('Purchase Invoice',
fields= fields, filters=filters)
def get_report_filters(report_filters):
filters = [['Purchase Invoice','company','=',report_filters.get('company')],
['Purchase Invoice','posting_date','<=',report_filters.get('posting_date')], ['Purchase Invoice','docstatus','=',1],
['Purchase Invoice','per_received','<',100], ['Purchase Invoice','update_stock','=',0]]
if report_filters.get('purchase_invoice'):
filters.append(['Purchase Invoice','per_received','in',[report_filters.get('purchase_invoice')]])
return filters
def get_report_fields():
fields = []
for p_field in ['name', 'supplier', 'company', 'posting_date', 'currency']:
fields.append('`tabPurchase Invoice`.`{}`'.format(p_field))
for c_field in ['item_code', 'item_name', 'uom', 'qty', 'received_qty', 'rate', 'amount']:
fields.append('`tabPurchase Invoice Item`.`{}`'.format(c_field))
return fields
def get_columns():
return [
{
'label': _('Purchase Invoice'),
'fieldname': 'name',
'fieldtype': 'Link',
'options': 'Purchase Invoice',
'width': 170
},
{
'label': _('Supplier'),
'fieldname': 'supplier',
'fieldtype': 'Link',
'options': 'Supplier',
'width': 120
},
{
'label': _('Posting Date'),
'fieldname': 'posting_date',
'fieldtype': 'Date',
'width': 100
},
{
'label': _('Item Code'),
'fieldname': 'item_code',
'fieldtype': 'Link',
'options': 'Item',
'width': 100
},
{
'label': _('Item Name'),
'fieldname': 'item_name',
'fieldtype': 'Data',
'width': 100
},
{
'label': _('UOM'),
'fieldname': 'uom',
'fieldtype': 'Link',
'options': 'UOM',
'width': 100
},
{
'label': _('Invoiced Qty'),
'fieldname': 'qty',
'fieldtype': 'Float',
'width': 100
},
{
'label': _('Received Qty'),
'fieldname': 'received_qty',
'fieldtype': 'Float',
'width': 100
},
{
'label': _('Rate'),
'fieldname': 'rate',
'fieldtype': 'Currency',
'width': 100
},
{
'label': _('Amount'),
'fieldname': 'amount',
'fieldtype': 'Currency',
'width': 100
}
]

View File

@@ -5,7 +5,7 @@ from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import cint, cstr
from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data)
from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data, get_filtered_list_for_consolidated_report)
from erpnext.accounts.report.profit_and_loss_statement.profit_and_loss_statement import get_net_profit_loss
from erpnext.accounts.utils import get_fiscal_year
from six import iteritems
@@ -67,9 +67,9 @@ def execute(filters=None):
section_data.append(account_data)
add_total_row_account(data, section_data, cash_flow_account['section_footer'],
period_list, company_currency, summary_data)
period_list, company_currency, summary_data, filters)
add_total_row_account(data, data, _("Net Change in Cash"), period_list, company_currency, summary_data)
add_total_row_account(data, data, _("Net Change in Cash"), period_list, company_currency, summary_data, filters)
columns = get_columns(filters.periodicity, period_list, filters.accumulated_values, filters.company)
chart = get_chart_data(columns, data)
@@ -162,18 +162,26 @@ def get_start_date(period, accumulated_values, company):
return start_date
def add_total_row_account(out, data, label, period_list, currency, summary_data, consolidated = False):
def add_total_row_account(out, data, label, period_list, currency, summary_data, filters, consolidated=False):
total_row = {
"account_name": "'" + _("{0}").format(label) + "'",
"account": "'" + _("{0}").format(label) + "'",
"currency": currency
}
summary_data[label] = 0
# from consolidated financial statement
if filters.get('accumulated_in_group_company'):
period_list = get_filtered_list_for_consolidated_report(filters, period_list)
for row in data:
if row.get("parent_account"):
for period in period_list:
key = period if consolidated else period['key']
total_row.setdefault(key, 0.0)
total_row[key] += row.get(key, 0.0)
summary_data[label] += row.get(key)
total_row.setdefault("total", 0.0)
total_row["total"] += row["total"]
@@ -181,7 +189,6 @@ def add_total_row_account(out, data, label, period_list, currency, summary_data,
out.append(total_row)
out.append({})
summary_data[label] = total_row["total"]
def get_report_summary(summary_data, currency):
report_summary = []

View File

@@ -2,118 +2,128 @@
// For license information, please see license.txt
/* eslint-disable */
frappe.query_reports["Consolidated Financial Statement"] = {
"filters": [
{
"fieldname":"company",
"label": __("Company"),
"fieldtype": "Link",
"options": "Company",
"default": frappe.defaults.get_user_default("Company"),
"reqd": 1
},
{
"fieldname":"filter_based_on",
"label": __("Filter Based On"),
"fieldtype": "Select",
"options": ["Fiscal Year", "Date Range"],
"default": ["Fiscal Year"],
"reqd": 1,
on_change: function() {
let filter_based_on = frappe.query_report.get_filter_value('filter_based_on');
frappe.query_report.toggle_filter_display('from_fiscal_year', filter_based_on === 'Date Range');
frappe.query_report.toggle_filter_display('to_fiscal_year', filter_based_on === 'Date Range');
frappe.query_report.toggle_filter_display('period_start_date', filter_based_on === 'Fiscal Year');
frappe.query_report.toggle_filter_display('period_end_date', filter_based_on === 'Fiscal Year');
frappe.require("assets/erpnext/js/financial_statements.js", function() {
frappe.query_reports["Consolidated Financial Statement"] = {
"filters": [
{
"fieldname":"company",
"label": __("Company"),
"fieldtype": "Link",
"options": "Company",
"default": frappe.defaults.get_user_default("Company"),
"reqd": 1
},
{
"fieldname":"filter_based_on",
"label": __("Filter Based On"),
"fieldtype": "Select",
"options": ["Fiscal Year", "Date Range"],
"default": ["Fiscal Year"],
"reqd": 1,
on_change: function() {
let filter_based_on = frappe.query_report.get_filter_value('filter_based_on');
frappe.query_report.toggle_filter_display('from_fiscal_year', filter_based_on === 'Date Range');
frappe.query_report.toggle_filter_display('to_fiscal_year', filter_based_on === 'Date Range');
frappe.query_report.toggle_filter_display('period_start_date', filter_based_on === 'Fiscal Year');
frappe.query_report.toggle_filter_display('period_end_date', filter_based_on === 'Fiscal Year');
frappe.query_report.refresh();
frappe.query_report.refresh();
}
},
{
"fieldname":"period_start_date",
"label": __("Start Date"),
"fieldtype": "Date",
"hidden": 1,
"reqd": 1
},
{
"fieldname":"period_end_date",
"label": __("End Date"),
"fieldtype": "Date",
"hidden": 1,
"reqd": 1
},
{
"fieldname":"from_fiscal_year",
"label": __("Start Year"),
"fieldtype": "Link",
"options": "Fiscal Year",
"default": frappe.defaults.get_user_default("fiscal_year"),
"reqd": 1
},
{
"fieldname":"to_fiscal_year",
"label": __("End Year"),
"fieldtype": "Link",
"options": "Fiscal Year",
"default": frappe.defaults.get_user_default("fiscal_year"),
"reqd": 1
},
{
"fieldname":"finance_book",
"label": __("Finance Book"),
"fieldtype": "Link",
"options": "Finance Book"
},
{
"fieldname":"report",
"label": __("Report"),
"fieldtype": "Select",
"options": ["Profit and Loss Statement", "Balance Sheet", "Cash Flow"],
"default": "Balance Sheet",
"reqd": 1
},
{
"fieldname": "presentation_currency",
"label": __("Currency"),
"fieldtype": "Select",
"options": erpnext.get_presentation_currency_list(),
"default": frappe.defaults.get_user_default("Currency")
},
{
"fieldname":"accumulated_in_group_company",
"label": __("Accumulated Values in Group Company"),
"fieldtype": "Check",
"default": 0
},
{
"fieldname": "include_default_book_entries",
"label": __("Include Default Book Entries"),
"fieldtype": "Check",
"default": 1
}
],
"formatter": function(value, row, column, data, default_formatter) {
if (data && column.fieldname=="account") {
value = data.account_name || value;
column.link_onclick =
"erpnext.financial_statements.open_general_ledger(" + JSON.stringify(data) + ")";
column.is_tree = true;
}
},
{
"fieldname":"period_start_date",
"label": __("Start Date"),
"fieldtype": "Date",
"hidden": 1,
"reqd": 1
},
{
"fieldname":"period_end_date",
"label": __("End Date"),
"fieldtype": "Date",
"hidden": 1,
"reqd": 1
},
{
"fieldname":"from_fiscal_year",
"label": __("Start Year"),
"fieldtype": "Link",
"options": "Fiscal Year",
"default": frappe.defaults.get_user_default("fiscal_year"),
"reqd": 1
},
{
"fieldname":"to_fiscal_year",
"label": __("End Year"),
"fieldtype": "Link",
"options": "Fiscal Year",
"default": frappe.defaults.get_user_default("fiscal_year"),
"reqd": 1
},
{
"fieldname":"finance_book",
"label": __("Finance Book"),
"fieldtype": "Link",
"options": "Finance Book"
},
{
"fieldname":"report",
"label": __("Report"),
"fieldtype": "Select",
"options": ["Profit and Loss Statement", "Balance Sheet", "Cash Flow"],
"default": "Balance Sheet",
"reqd": 1
},
{
"fieldname": "presentation_currency",
"label": __("Currency"),
"fieldtype": "Select",
"options": erpnext.get_presentation_currency_list(),
"default": frappe.defaults.get_user_default("Currency")
},
{
"fieldname":"accumulated_in_group_company",
"label": __("Accumulated Values in Group Company"),
"fieldtype": "Check",
"default": 0
},
{
"fieldname": "include_default_book_entries",
"label": __("Include Default Book Entries"),
"fieldtype": "Check",
"default": 1
}
],
"formatter": function(value, row, column, data, default_formatter) {
value = default_formatter(value, row, column, data);
if (!data.parent_account) {
value = $(`<span>${value}</span>`);
value = default_formatter(value, row, column, data);
var $value = $(value).css("font-weight", "bold");
if (!data.parent_account) {
value = $(`<span>${value}</span>`);
value = $value.wrap("<p></p>").parent().html();
}
return value;
},
onload: function() {
let fiscal_year = frappe.defaults.get_user_default("fiscal_year")
var $value = $(value).css("font-weight", "bold");
frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
frappe.query_report.set_filter_value({
period_start_date: fy.year_start_date,
period_end_date: fy.year_end_date
value = $value.wrap("<p></p>").parent().html();
}
return value;
},
onload: function() {
let fiscal_year = frappe.defaults.get_user_default("fiscal_year")
frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
frappe.query_report.set_filter_value({
period_start_date: fy.year_start_date,
period_end_date: fy.year_end_date
});
});
});
}
}
}
});

View File

@@ -94,7 +94,7 @@ def get_profit_loss_data(fiscal_year, companies, columns, filters):
chart = get_pl_chart_data(filters, columns, income, expense, net_profit_loss)
report_summary = get_pl_summary(companies, '', income, expense, net_profit_loss, company_currency, True)
report_summary = get_pl_summary(companies, '', income, expense, net_profit_loss, company_currency, filters, True)
return data, None, chart, report_summary
@@ -149,9 +149,9 @@ def get_cash_flow_data(fiscal_year, companies, filters):
section_data.append(account_data)
add_total_row_account(data, section_data, cash_flow_account['section_footer'],
companies, company_currency, summary_data, True)
companies, company_currency, summary_data, filters, True)
add_total_row_account(data, data, _("Net Change in Cash"), companies, company_currency, summary_data, True)
add_total_row_account(data, data, _("Net Change in Cash"), companies, company_currency, summary_data, filters, True)
report_summary = get_cash_flow_summary(summary_data, company_currency)
@@ -329,8 +329,9 @@ def prepare_data(accounts, start_date, end_date, balance_must_be, companies, com
has_value = False
total = 0
row = frappe._dict({
"account_name": _(d.account_name),
"account": _(d.account_name),
"account_name": ('%s - %s' %(_(d.account_number), _(d.account_name))
if d.account_number else _(d.account_name)),
"account": _(d.name),
"parent_account": _(d.parent_account),
"indent": flt(d.indent),
"year_start_date": start_date,

View File

@@ -119,10 +119,10 @@ def validate_fiscal_year(fiscal_year, from_fiscal_year, to_fiscal_year):
def validate_dates(from_date, to_date):
if not from_date or not to_date:
frappe.throw("From Date and To Date are mandatory")
frappe.throw(_("From Date and To Date are mandatory"))
if to_date < from_date:
frappe.throw("To Date cannot be less than From Date")
frappe.throw(_("To Date cannot be less than From Date"))
def get_months(start_date, end_date):
diff = (12 * end_date.year + end_date.month) - (12 * start_date.year + start_date.month)
@@ -522,4 +522,12 @@ def get_columns(periodicity, period_list, accumulated_values=1, company=None):
"width": 150
})
return columns
return columns
def get_filtered_list_for_consolidated_report(filters, period_list):
filtered_summary_list = []
for period in period_list:
if period == filters.get('company'):
filtered_summary_list.append(period)
return filtered_summary_list

View File

@@ -116,22 +116,19 @@ def validate_filters(filters):
frappe.throw(_("Can not filter based on Payment Method, if grouped by Payment Method"))
def get_conditions(filters):
conditions = "company = %(company)s AND posting_date >= %(from_date)s AND posting_date <= %(to_date)s".format(
company=filters.get("company"),
from_date=filters.get("from_date"),
to_date=filters.get("to_date"))
conditions = "company = %(company)s AND posting_date >= %(from_date)s AND posting_date <= %(to_date)s"
if filters.get("pos_profile"):
conditions += " AND pos_profile = %(pos_profile)s".format(pos_profile=filters.get("pos_profile"))
conditions += " AND pos_profile = %(pos_profile)s"
if filters.get("owner"):
conditions += " AND owner = %(owner)s".format(owner=filters.get("owner"))
conditions += " AND owner = %(owner)s"
if filters.get("customer"):
conditions += " AND customer = %(customer)s".format(customer=filters.get("customer"))
conditions += " AND customer = %(customer)s"
if filters.get("is_return"):
conditions += " AND is_return = %(is_return)s".format(is_return=filters.get("is_return"))
conditions += " AND is_return = %(is_return)s"
if filters.get("mode_of_payment"):
conditions += """

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