Compare commits

..

493 Commits

Author SHA1 Message Date
Sahil Khan
9a858a9824 Merge branch 'hotfix' 2019-07-11 15:15:56 +05:30
Sahil Khan
5792d6037c bumped to version 11.1.46 2019-07-11 15:35:56 +05:50
Nabin Hait
75310637da fix: Revert #frappe/erpnext/17896 (#18250) 2019-07-11 14:39:38 +05:30
Mangesh-Khairnar
6fa4697efb fix(sales-invoice): get items from quotation (#18236) 2019-07-11 10:05:03 +05:30
Suraj Shetty
68d7d6e223 fix: Return fieldtype so that the client-side can format chart values (#18221) 2019-07-10 17:16:48 +05:30
Nabin Hait
7ee97b6128 fix: Make material request against SO only for pending qty (#18217) 2019-07-10 17:05:57 +05:30
Mangesh-Khairnar
49fadcbaf2 fix(exchange-rate-revaluation): change create to view button on creation of journal entry (#18202) 2019-07-10 17:03:08 +05:30
rohitwaghchaure
e6ab86e185 fix: error report for item price (#18213) 2019-07-10 16:41:39 +05:30
Sahil Khan
35fe0a6cbd Merge branch 'hotfix' 2019-07-09 15:20:08 +05:30
Sahil Khan
d287fe4dae bumped to version 11.1.45 2019-07-09 15:40:08 +05:50
Mangesh-Khairnar
683d987432 fix(bom): escape name with wildcard character (#18163) 2019-07-08 10:40:24 +05:30
rohitwaghchaure
37d0c75f04 fix: not able to make credit note for the sales invoice in which item code is not set (#18185) 2019-07-08 10:26:12 +05:30
Deepesh Garg
6940a6cd47 Merge pull request #18196 from deepeshgarg007/b2cs_json_hotfix
fix: Cess amount calculation fix in GSTR-1 report (hotfix)
2019-07-08 10:11:06 +05:30
deepeshgarg007
34867ced92 fix: Cess amount calculation fix in GSTR-1(hotfix) 2019-07-07 21:49:17 +05:30
rohitwaghchaure
7543916da6 Merge pull request #18153 from netchampfaris/fix-price-list-on-website
fix: Honor price list in Shopping Cart Settings
2019-07-05 18:14:06 +05:30
rohitwaghchaure
11d02c028f fix: on credit note / debit note deferred reversed instead of income (#18171) 2019-07-05 14:19:40 +05:30
rohitwaghchaure
a72ef5eceb Merge pull request #18159 from rohitwaghchaure/set_default_supplier_in_item_default_for_multi_company
fix: default supplier was not set from the patch in item defaults for multi company instance
2019-07-05 11:21:34 +05:30
Sahil Khan
3e9ddf23e1 Merge branch 'hotfix' 2019-07-04 15:50:39 +05:30
Sahil Khan
6fc6f385fe bumped to version 11.1.44 2019-07-04 16:10:39 +05:50
Rohit Waghchaure
ba62173561 fix: default supplier was not set from the patch in item defaults for multi company instance 2019-07-04 15:00:04 +05:30
Mangesh-Khairnar
709f21692c fix(salary-slip): amount calculation (#18158) 2019-07-04 13:09:06 +05:30
Mangesh-Khairnar
4dd48f46f3 fix: invoice cancellation (#18151) 2019-07-04 11:37:45 +05:30
Faris Ansari
e59836e3da fix: Honor price list in Shopping Cart Settings 2019-07-03 19:22:49 +05:30
Mangesh-Khairnar
cc80be449d fix: Salary slip amount calculation (#18146) 2019-07-03 17:27:40 +05:30
Anurag Mishra
29433f2b1b fix: translating Error (#18140) 2019-07-03 11:42:33 +05:30
Sahil Khan
bdeaf4880f Merge branch 'hotfix' 2019-07-02 18:46:20 +05:30
Sahil Khan
53e3674924 bumped to version 11.1.43 2019-07-02 19:06:20 +05:50
rohitwaghchaure
6f2f8ae85e Merge pull request #18128 from rohitwaghchaure/fixed_issues_in_delayed_order_report
fix: multiple minor issues in delayed order report
2019-07-02 12:46:04 +05:30
Deepesh Garg
48474a2d4e fix: Fiter passing fix in get batch query (#18130) 2019-07-02 10:11:02 +05:30
rohitwaghchaure
3e6df7f0bb Merge pull request #18103 from rohitwaghchaure/incorrect_value_of_accumualated_depreciation_in_the_sales_invoice
fix: incorrect value booked in the accumulated depreciation account on sell of the asset
2019-07-01 20:43:35 +05:30
Rohit Waghchaure
47bca7f651 fix: multiple minor issues in delayed order report 2019-07-01 20:38:27 +05:30
Shivam Mishra
fb59d770ba fix: translated title (#18121) 2019-07-01 11:01:36 +00:00
Nabin Hait
ad99934b4c Update accounts_controller.py 2019-07-01 15:16:10 +05:30
Rohit Waghchaure
2a0be68cb3 fix: incorrect value booked in the accumulated depreciation account on sell of the asset 2019-07-01 13:26:58 +05:30
Mangesh-Khairnar
a7da7226ac Merge pull request #18106 from Mangesh-Khairnar/fix-mapped-doc
fix: clear duplicates in mapped doc
2019-07-01 12:27:24 +05:30
Himanshu
84d3d544ef Merge branch 'hotfix' into fix-mapped-doc 2019-06-28 19:46:29 +05:30
Mangesh-Khairnar
30c9c56d6c fix: add a more descriptive message when no records are found (#18083)
* fix: add a more descriptive message when no records are found

* fix: translation by passing string to translation function
2019-06-28 19:35:05 +05:30
Mangesh-Khairnar
dfe0a9002a fix: mapped doc 2019-06-28 19:26:18 +05:30
rohitwaghchaure
3eea9e3967 Merge pull request #18101 from adityahase/fix-buying
fix(buying): Translate label for "Supplier Addresses And Contacts" Report
2019-06-28 14:43:52 +05:30
Aditya Hase
69051c4197 fix(buying): Translate label for "Supplier Addresses And Contacts" Report 2019-06-28 14:36:53 +05:30
Himanshu
5b5156356a fix(Utils): Do not add duplicate item to items (#17895)
* fix: do not add duplicate item to items

* fix: compare warehouses, batch and qty for an item

* fix: code fixes

* Update utils.js

* fix: check required_date and delivery_date

* Update utils.js

* Update utils.js

* Update utils.js

* fix: mixed spaces and tabs
2019-06-28 14:12:40 +05:30
Deepesh Garg
fdd1422d31 fix: Usability fixes to Serial No and batch selector (#18070)
* fix: Usability fixes to Serial No and batch selector

* fix: Codacy

* Update sales_common.js
2019-06-28 14:09:23 +05:30
rohitwaghchaure
c82253e479 fix: not able to make salary slip based on timesheet (#18087) 2019-06-28 12:41:16 +05:30
Nabin Hait
b059c6f630 fix: Fixes related to customer/lead merging (#18075) 2019-06-28 12:36:27 +05:30
Anurag Mishra
42e62bd1b4 fix: Wrong Casual Leave Opening in Employee Leave Balance Report
fix: Wrong Casual Leave Opening in Employee Leave Balance Report
2019-06-27 17:01:21 +05:30
Rushabh Mehta
2ff9c385c3 Merge pull request #18080 from Mangesh-Khairnar/department-fix
fix: open department in tree view via awesome bar
2019-06-27 15:02:57 +05:30
Anurag Mishra
804b80ac7b Merge branch 'hotfix' into wrong_Casual_Leave_opening 2019-06-27 13:48:57 +05:30
Saurabh
25eff13d35 Merge branch 'hotfix' 2019-06-27 12:51:14 +05:30
Saurabh
415c90d9d0 bumped to version 11.1.42 2019-06-27 13:21:14 +06:00
rohitwaghchaure
97a49185c5 Merge pull request #18091 from rohitwaghchaure/same_taxes_adding_multiple_times_in_pos
fix: same taxes adding multiple times in pos
2019-06-27 12:14:23 +05:30
Mangesh-Khairnar
e68d4c897b fix: open department in tree view via awesome bar 2019-06-27 11:41:17 +05:30
Anurag Mishra
76640cbad6 Merge branch 'hotfix' into wrong_Casual_Leave_opening 2019-06-27 11:20:24 +05:30
Rohit Waghchaure
c2e5e569a0 fix: same taxes adding multiple times in pos 2019-06-27 11:15:18 +05:30
rohitwaghchaure
d5384a110d Merge pull request #18084 from rohitwaghchaure/fix_test_cases_for_sales_invoice_for_dn
fix: dn test cases
2019-06-26 22:52:10 +05:30
Rohit Waghchaure
4e9f1a08fe fix: dn test cases 2019-06-26 21:57:03 +05:30
Anurag Mishra
e20e38d530 Merge branch 'hotfix' into wrong_Casual_Leave_opening 2019-06-26 18:28:59 +05:30
Saurabh
79f2779574 Merge branch 'hotfix' 2019-06-26 17:18:50 +05:30
Saurabh
23251d9e4d bumped to version 11.1.41 2019-06-26 17:48:50 +06:00
Aditya Hase
e2652b9cc5 fix(item): moving reload_doc up in item barcode patch (#18078)
fix(item): moving reload_doc up in item barcode patch
2019-06-26 17:14:37 +05:30
karthikeyan5
beca677276 fix(item): fixing broken patch item_barcode_childtable_migrate 2019-06-26 17:11:14 +05:30
Sahil Khan
1202dc1dd3 Merge branch 'hotfix' 2019-06-26 15:53:52 +05:30
Sahil Khan
e2ddc82637 bumped to version 11.1.40 2019-06-26 16:13:52 +05:50
rohitwaghchaure
f269b66f39 fix: returned qty issue while making sales invoice from dn if same item added multiple times (#18074) 2019-06-26 13:39:52 +05:30
Rushabh Mehta
850284abee Merge pull request #18073 from hrwX/att_gantt_fix
fix(Attendance): Attendance gantt view
2019-06-26 13:36:49 +05:30
Anurag Mishra
b3dec74c6a fix: removed unused function 2019-06-26 13:31:09 +05:30
Faris Ansari
a6a6171225 fix: Don't append None values in against_account (#18032) 2019-06-26 13:30:54 +05:30
Anurag Mishra
cf77740ab1 fix: wrong Casual Leave opening 2019-06-26 13:29:02 +05:30
Himanshu Warekar
836aa5a1e6 fix: attendance gantt view 2019-06-26 11:35:53 +05:30
Mangesh-Khairnar
453d484a96 fix: precision for certain calculations in buying controller (#18009)
* fix: precision for certain numbers

* fix: check precision of the received_qty

* Update buying_controller.py
2019-06-26 11:09:39 +05:30
Deepesh Garg
3957880370 fix: Removed submitted status from quotation (#18054)
* fix: Change in list view and status updater

* fix: Change status in doctype

* fix: Patch for submitted status
2019-06-26 11:06:14 +05:30
Mangesh-Khairnar
840bfa87e8 fix: change the department to tree view (#18056) 2019-06-26 11:03:36 +05:30
Karthikeyan S
b2c43ee2d9 fix(item): fix patch for barcode childtable migration in item (#18066)
* fix(item): fix patch for barcode childtable migration in item

* fix(item): fix patch for barcode childtable migration in item

> adding condition so this patch will not execute for the site where it was executed perfectly the first time
2019-06-26 11:00:17 +05:30
Nabin Hait
10878c4d0e fix: Show close button if per_ordered is less than 99.999999 (#18068) 2019-06-26 10:57:39 +05:30
rohitwaghchaure
7cb940b179 Merge pull request #18043 from rohitwaghchaure/closed_job_opening_disaplying_in_job_applicant_hotfix
fix: Closed job opening disaplying in job applicant
2019-06-25 16:51:30 +05:30
rohitwaghchaure
01c85e0420 Merge pull request #18048 from deepeshgarg007/rounded_total
fix: Currency symbol fix for rounded total
2019-06-25 16:50:45 +05:30
rohitwaghchaure
41f36a6d92 Merge pull request #18027 from adityahase/fix-remove-imports
style: Remove unused imports
2019-06-25 15:41:44 +05:30
rohitwaghchaure
2aff5384ec Merge pull request #18044 from deepeshgarg007/accounts-controller
fix: Float division by zero error handling in group similar item
2019-06-25 15:25:17 +05:30
rohitwaghchaure
e592891121 Merge pull request #18039 from Mangesh-Khairnar/price-list-fix
fix(price list): change the field name
2019-06-25 15:23:13 +05:30
Deepesh Garg
e263a10fdd Merge pull request #18051 from karthikeyan5/hotfix-woocommerce-log
fix(integrations): Adding Error Logs for Woocommerce
2019-06-25 15:11:33 +05:30
rohitwaghchaure
db8b6c59bc Merge pull request #18018 from frappe/fix_bom_include_exploded_item
fix(BOM): set default value of include_exploded_item to 0
2019-06-25 14:19:00 +05:30
sahil28297
e1f3da2c2d Merge branch 'hotfix' into fix_bom_include_exploded_item 2019-06-25 14:09:47 +05:30
karthikeyan5
ae255d6328 Fix(integrations): Adding Error Logs for Woocommerce 2019-06-25 14:01:13 +05:30
Deepesh Garg
c283329581 Merge branch 'hotfix' into accounts-controller 2019-06-25 13:15:50 +05:30
Deepesh Garg
f85e344ed4 Merge branch 'hotfix' into rounded_total 2019-06-25 13:15:33 +05:30
rohitwaghchaure
aece8056f8 Merge pull request #18041 from rohitwaghchaure/fixed_test_case_for_payment_terms_in_so_hotfix
fix: test cases for quotation
2019-06-25 06:38:55 +05:30
deepeshgarg007
5d6ccafac9 fix: Currency symbol fix for rounded total 2019-06-24 21:12:16 +05:30
Rohit Waghchaure
ee22706182 fix: Closed job opening disaplying in job applicant 2019-06-24 18:04:28 +05:30
rohitwaghchaure
013ae1172a Merge pull request #17986 from rohitwaghchaure/all_default_values_not_moved_to_item_default_table
fix: as limit 100 was set in the query therefore not all item's default value moved to the Item Default table
2019-06-24 17:59:44 +05:30
deepeshgarg007
069276473f fix: Division by zero error fix in group similar item 2019-06-24 17:46:44 +05:30
Rohit Waghchaure
a8289d4fd5 fix: test case for payment terms in quotation 2019-06-24 17:45:22 +05:30
Mangesh-Khairnar
2ed653f433 fix(price list): change the field name 2019-06-24 17:29:11 +05:30
sahil28297
b724e080b0 fix(BOM): update modified field 2019-06-23 20:05:02 +05:30
Aditya Hase
9de95528ef style: Remove unused imports 2019-06-21 22:57:31 +05:30
Aditya Hase
3cab94f130 chore: Python 3 Tests on Travis (#18016)
chore: Python 3 Tests on Travis
2019-06-21 22:33:10 +05:30
Aditya Hase
b2cf38bbf4 Merge branch 'hotfix' into py3-hotfix 2019-06-21 21:36:03 +05:30
Aditya Hase
6c7bfb37c1 fix: Python 3 compatibility fixes (#18024)
fix: Python 3 compatibility fixes
2019-06-21 21:35:46 +05:30
Aditya Hase
6edd2b7f9f fix(py3): Convert filter to list 2019-06-21 17:58:45 +05:30
Aditya Hase
b47caf6642 fix(py3): Convert dict.values() to list 2019-06-21 17:56:58 +05:30
Aditya Hase
67476e7e09 fix(py3): Convert filter to list 2019-06-21 17:52:51 +05:30
Aditya Hase
3bafada5a6 fix(py3): Convert per_billed explicitly to int before comparing 2019-06-21 17:51:45 +05:30
Aditya Hase
0743610487 Merge branch 'hotfix' into py3-hotfix 2019-06-21 12:58:16 +05:30
Aditya Hase
bc7d39a16b fix: Python 3 compatibility fixes (#18019)
fix: Python 3 compatibility fixes
2019-06-21 12:57:52 +05:30
Aditya Hase
618146cc63 fix(py3): Replace unicode with six.text_type 2019-06-21 12:09:44 +05:30
Aditya Hase
4acd39b6a4 fix(py3): Convert filter to list 2019-06-21 12:08:23 +05:30
Aditya Hase
72056c26a8 fix(py3): Undefined variable 2019-06-21 12:06:05 +05:30
Aditya Hase
fbab41668d fix(py3): Undefined variable 2019-06-21 12:06:05 +05:30
Aditya Hase
14b5c96c58 fix(py3): Use range instead of xrange 2019-06-21 12:06:05 +05:30
Aditya Hase
d48d5c7cbd fix: Replace unicode with six.text_type 2019-06-21 12:06:05 +05:30
Aditya Hase
3d59ab5c55 fix(tests): Do not test order of features in Location 2019-06-21 12:06:05 +05:30
Aditya Hase
12cb0ea633 fix(tests): Timesheet tests 2019-06-21 12:06:05 +05:30
sahil28297
c5e959fe9c fix(BOM): set default value of include_exploded_item to 0 2019-06-21 11:42:58 +05:30
Aditya Hase
13d01dd690 fix: Run script with bash 2019-06-21 11:24:56 +05:30
Aditya Hase
4e94e26ef8 fix: Minor 2019-06-21 11:24:47 +05:30
Aditya Hase
8738f2e1c9 fix: Set file permissions 755 on travis/run-tests.sh 2019-06-21 11:24:39 +05:30
Aditya Hase
508b3ab8de fix(travis): Refactor .travis.yml 2019-06-21 11:24:28 +05:30
Aditya Hase
8f1f6a89f1 feat(travis): Python 3.6 tests 2019-06-21 11:24:14 +05:30
Rohit Waghchaure
523d89a2d9 fix: as limit 100 was set in the query therefore not all item's default value moved to the Item Default table 2019-06-21 10:24:08 +05:30
Rushabh Mehta
8d45d5c4a7 Merge pull request #16896 from Alchez/hotfix-shipping-override
fix(transaction): Fix shipping rule charge override by tax template
2019-06-21 09:25:14 +05:30
Rushabh Mehta
437edb1f01 Merge pull request #17391 from ashish-greycube/copy_payment_schedule_from_quot_to_SO
fix: copy_payment_schedule_from_quot_to_SO
2019-06-21 09:19:41 +05:30
Deepesh Garg
ac57edf7d3 fix: Default cost center fix for delivery note item (#17988) 2019-06-20 19:12:16 +05:30
Rushabh Mehta
3a2fec1ffb Merge pull request #17917 from Alchez/hotfix-item-code-gen
fix(stock): Remove hardcoded validation for Item
2019-06-20 14:21:46 +05:30
Deepesh Garg
e2cf17e106 Merge pull request #17994 from deepeshgarg007/hsn_summary
fix: From date and to date filters in HSN wise summary of outward supplies
2019-06-19 21:48:33 +05:30
deepeshgarg007
e5c7f3e542 fix: From date and to date filters in HSN wise summary of out ward supplies 2019-06-19 18:25:38 +05:30
rohitwaghchaure
d2bbc3ef3e Merge pull request #17966 from Alchez/fix-delivery-email
fix(delivery): Add items to context for dispatch notification email
2019-06-19 14:36:34 +05:30
rohitwaghchaure
96b6cfd810 Merge pull request #17979 from rohitwaghchaure/added_include_default_finance_book_in_reports
fix: finance book filters includes the gl data which don't have finance book
2019-06-19 14:09:35 +05:30
rohitwaghchaure
b3cf5f0caa Merge pull request #17977 from rohitwaghchaure/employee_attendance_tool_ux_issue
fix: could not find company all
2019-06-19 14:08:33 +05:30
Rohit Waghchaure
072948e827 fix: finance book filters includes the gl data which don't have finance book 2019-06-18 18:34:14 +05:30
Rohit Waghchaure
8ef80fb669 fix: could not find company all 2019-06-18 16:09:17 +05:30
Sahil Khan
4de1083096 Merge branch 'hotfix' 2019-06-18 14:41:56 +05:30
Sahil Khan
e5647f7441 bumped to version 11.1.39 2019-06-18 15:01:56 +05:50
Suraj Shetty
f9318f82ae Merge pull request #17971 from Mangesh-Khairnar/benefit-application
fix(employee-benefit-application): remove query from setup
2019-06-18 14:37:11 +05:30
rohitwaghchaure
4f78d14471 Merge pull request #17963 from rohitwaghchaure/bank_guarantee_project_not_found_error
fix: bank guarantee, not able to select the purchase order
2019-06-18 11:30:42 +05:30
rohitwaghchaure
d41771b4b1 Merge pull request #17961 from rohitwaghchaure/not_able_to_save_asset_for_manual_method
fix: not able to save asset if depreciation method is manual
2019-06-18 11:29:39 +05:30
Anurag Mishra
0c7afb389d fix: Company Filter in Total Stock Summary Report (#17973) 2019-06-17 20:48:11 +05:30
Mangesh-Khairnar
77ed46242f fix: change formatting 2019-06-17 19:04:13 +05:30
Mangesh-Khairnar
acbdeb833f fix(employee-benefit-application): remove query from setup 2019-06-17 18:08:48 +05:30
Rohit Waghchaure
2493d5e0d3 fix: bank guarantee, not able to select the purchase order 2019-06-17 17:39:37 +05:30
rohitwaghchaure
820d66b42e Merge pull request #17968 from rohitwaghchaure/enabled_disabled_buttons_on_change_of_pos_profile
fix: allow edit is enabled in the pos profile still user not able to edit the rates
2019-06-17 17:24:14 +05:30
Rohit Waghchaure
8fb018de47 fix: allow edit is enabled in the pos profile still user not able to edit the rates 2019-06-17 16:19:23 +05:30
Rohan Bansal
7987b1a681 fix(delivery): Add more context for dispatch notification email + formatting fixes 2019-06-17 16:13:52 +05:30
Rushabh Mehta
750526b138 Merge pull request #17928 from nabinhait/get-items-from
fix: Fixed setters for getting items from quotation/opportunity
2019-06-17 14:31:49 +05:30
Rohit Waghchaure
6b5c365cb6 fix: not able to save asset if depreciation method is manual 2019-06-17 13:32:36 +05:30
rohitwaghchaure
1a5c0b3ae2 Merge pull request #17957 from rohitwaghchaure/revert_group_by_voucher_general_ledger
fix: revert group by voucher general ledger changes
2019-06-17 07:43:53 +05:30
Rohit Waghchaure
740c954679 fix: revert group by voucher general ledger changes 2019-06-17 07:40:21 +05:30
Rohan
c8b1fbd9e6 Merge branch 'hotfix' into hotfix-item-code-gen 2019-06-14 15:53:11 +05:30
Khadija Tul Kubra Zaki
dc24fe60be fix: leave without pay spelling in salary register (#17938)
* leave without pay spelling in salary register

* fixed typo
2019-06-14 11:59:45 +05:30
Rushabh Mehta
86b33b2a10 Merge pull request #17369 from alyf-de/datev_report
feat(regional): Report for German tax consultants (DATEV)
2019-06-14 11:49:20 +05:30
Anurag Mishra
1450a7b408 fix column width (#17936) 2019-06-14 11:29:29 +05:30
rohitwaghchaure
f7af9b8745 fix: trial balance opening balance not showing in the debit side for the liability account (#17786) 2019-06-14 11:22:23 +05:30
Saurabh
87a09d2bb3 Merge pull request #17940 from nabinhait/salary-slip-amount
fix: salary slip amount calculation based on formula
2019-06-14 11:20:01 +05:30
Rushabh Mehta
c5283903be Merge pull request #17893 from deepeshgarg007/serial_no_batch_selector
fix: Available qty not shown in item batch selector for batch
2019-06-14 10:51:08 +05:30
sahil28297
cfd6ec0dcb Merge branch 'hotfix' into serial_no_batch_selector 2019-06-13 19:51:47 +05:30
Nabin Hait
a59aaf48f2 fix: salary slip amount calculation based on formula 2019-06-13 19:43:47 +05:30
Shivam Mishra
c40d832e5e Merge pull request #17934 from Anurag810/billing_summary_fixes_v11
fix: column sequence and width
2019-06-13 17:27:12 +05:30
rohitwaghchaure
23f901c29a Merge pull request #17931 from rohitwaghchaure/fixed_pos_not_overriding_the_taxes
fix: taxes are not overriding after changing the tax template for the POS invoice
2019-06-13 16:25:56 +05:30
Shivam Mishra
c06d1ec73d Merge pull request #17926 from Mangesh-Khairnar/get-bom-items-fix
fix: Check fields before making BOM items
2019-06-13 16:17:58 +05:30
Anurag Mishra
2fc6d1d210 fix: column sequence and width 2019-06-13 16:09:30 +05:30
Rohit Waghchaure
49c6c909f8 fix: taxes are not overriding after changing the taxes template 2019-06-13 15:42:13 +05:30
Nabin Hait
ffd6b27f4b fix: Fixed setters for getting items from quotation/opportunity 2019-06-13 14:33:47 +05:30
Mangesh-Khairnar
860b6bac75 fix: get bom item when company is not passed 2019-06-13 14:28:46 +05:30
Rohan
9c3729b4ba Merge branch 'hotfix' into hotfix-item-code-gen 2019-06-13 14:23:36 +05:30
Rohan Bansal
1174e5a127 fix(stock): Remove hardcoded validation for Item 2019-06-12 17:56:17 +05:30
sahil28297
fe802a97a2 Merge branch 'hotfix' into serial_no_batch_selector 2019-06-12 13:11:32 +05:30
Sahil Khan
60f1750c96 Merge branch 'hotfix' 2019-06-11 17:03:41 +05:30
Sahil Khan
6a198acd2f bumped to version 11.1.38 2019-06-11 17:23:41 +05:50
rohitwaghchaure
40968c78a8 Merge pull request #17901 from rohitwaghchaure/general_leder_report_for_group_by_voucher_consolidated
fix: group by voucher condition for the general ledger report
2019-06-11 16:17:34 +05:30
Rohit Waghchaure
e03892b130 fix: group by voucher condition for the general ledger report 2019-06-11 14:17:06 +05:30
rohitwaghchaure
844bbcdb1d Merge pull request #17898 from rohitwaghchaure/general_ledger_group_by_voucher_consolidated_issue
fix: debit and credit showing in the same row if the group by is set as group by voucher (consolidated)
2019-06-11 11:39:33 +05:30
Nabin Hait
d77cd79262 Merge branch 'hotfix' 2019-06-10 19:16:11 +05:30
Nabin Hait
6e97f7fbd8 bumped to version 11.1.37 2019-06-10 19:36:10 +05:50
Rohit Waghchaure
de04941ddb fix: debit and credit showing in the same row if the group by is set as group by voucher (consolidated) 2019-06-10 18:31:41 +05:30
deepeshgarg007
2de80fdc3e fix: Codacy 2019-06-10 17:51:47 +05:30
Deepesh Garg
832884a7ea fix: Total Amount fix in journal entry (#17879) 2019-06-10 17:43:08 +05:30
sahil28297
4bc86c7e9d fix(patch): escape illegal characters to avoid SQL syntax error (#17889) 2019-06-10 17:38:42 +05:30
rohitwaghchaure
cd2938e2d0 fix: accounts receivable for PDC not showing 120 days column (#17892) 2019-06-10 17:38:17 +05:30
deepeshgarg007
1d11ddc235 fix: Available qty not shown in item batch selector for batch 2019-06-10 17:33:36 +05:30
rohitwaghchaure
f37a09d9fe Merge pull request #17618 from rohitwaghchaure/user_cogs_only_for_material_issue
feat: set COGS for material issue only
2019-06-10 16:56:34 +05:30
Rohit Waghchaure
978bc1352e stock_entry: set COGS for material issue only 2019-06-07 13:34:59 +05:30
rohitwaghchaure
ab669ad055 Merge pull request #17875 from rohitwaghchaure/salary_slip_update_component_row_error
fix: Not able to save salary slip
2019-06-07 12:58:07 +05:30
Deepesh Garg
443f9ed5f1 Merge pull request #17873 from sagarvora/ewb_fix
fix(regional): remove "Generate" from button text as button now under "Make" heading
2019-06-07 12:43:23 +05:30
Rohit Waghchaure
d72f4d7959 fix: Not able to save salary slip 2019-06-07 11:44:51 +05:30
Sagar Vora
4c23c2ddec fix (regional): remove "Generate" from button text as button now under "Make" heading 2019-06-07 10:37:26 +05:30
Prasann Shah
e0333c0756 [Add] GSTIN filter in HSN summary report (#17836)
* [Add] GSTIN filter in HSN summary report

* [Add] Same filter in GST Itemised Sales Register
2019-06-06 11:22:06 +05:30
Saurabh
066ae71581 Merge pull request #17863 from adityahase/fix-error-report-email-hotfix
fix(error-report): Do not send error reports to support@erpnext.com
2019-06-06 10:36:12 +05:30
Aditya Hase
2898c94f08 fix(error-report): Do not send error reports to support@erpnext.com 2019-06-05 23:31:13 +05:30
Nabin Hait
fc0df994b8 fix: Removed unwanted total row from financial statement and general ledger print (#17859) 2019-06-05 20:29:15 +05:30
Deepesh Garg
c5a4e423c6 fix: NoneType fixes in Lab test (#17856) 2019-06-05 20:23:41 +05:30
Sahil Khan
949f170b48 Merge branch 'hotfix' 2019-06-05 15:15:01 +05:30
Sahil Khan
576e68eef0 bumped to version 11.1.36 2019-06-05 15:35:01 +05:50
Deepesh Garg
63af463a9a fix: Patch for renaming enquiry_from to opportunity_from (#17785)
* fix: Patch for renaming enquiry_from to opportunity_from

* fix: Patch fix

* fix: patch fix

* fix: Use has_column instead of exists

* fix: Handled ifnull
2019-06-05 14:22:59 +05:30
Rohan
b20eda9996 fix(projects): Remove hardcode of expected end date for new Tasks (#17716) 2019-06-05 14:16:57 +05:30
Nabin Hait
88832daae4 feat: Rounding based on settings on salary component (#17851) 2019-06-05 13:20:18 +05:30
rohitwaghchaure
3aa2df29f5 Merge pull request #17850 from deepeshgarg007/italy-xml
fix: Update currency in Italy e-invoice XML
2019-06-05 11:42:37 +05:30
deepeshgarg007
42d0ee7431 fix: Update Italy e-invoice XML 2019-06-05 11:12:32 +05:30
rohitwaghchaure
15e128f321 Merge pull request #17838 from rohitwaghchaure/fix_payment_period_based_on_invoice_date_error
fix: report Payment Period Based On Invoice Date not working
2019-06-03 20:12:01 +05:30
Rohit Waghchaure
56757866f3 fix: report Payment Period Based On Invoice Date not working 2019-06-03 18:20:46 +05:30
Nabin Hait
c3f3c156b1 Merge pull request #17834 from deepeshgarg007/serial-no-fix
fix: Serial no filtering issue for delivered items
2019-06-03 14:25:17 +05:30
Nabin Hait
62e8955b39 Merge pull request #17806 from nabinhait/discount-rounding-adjustment
fix: Rounding adjustment while additional discount amount is applied on grand total
2019-06-03 13:08:57 +05:30
deepeshgarg007
fad3789f64 fix: Pass delivery document no as empty string 2019-06-03 13:04:57 +05:30
deepeshgarg007
a0b85d060b fix: Serial no filtering issue for delivered items 2019-06-03 11:57:00 +05:30
Saurabh
fd5d3f551b Merge pull request #17808 from Alchez/hotfix-sales-analytics-total
fix(selling): Remove Totals row for Sales Analytics
2019-05-31 14:28:10 +05:30
Saurabh
019014070d Merge pull request #17810 from nabinhait/pr-expense-account
fix: Added Expense Account field to push value from PO-PR-PI
2019-05-31 14:18:33 +05:30
Saurabh
97f5dff656 Merge pull request #17812 from rohitwaghchaure/allow_import_for_packing_slip
fix: allow import for packing slip
2019-05-31 14:15:16 +05:30
Deepesh Garg
0d28802485 Merge pull request #17815 from deepeshgarg007/ar_translation
fix: Add translations for missing labels in AR report
2019-05-31 12:37:18 +05:30
Saurabh
254774f7a3 Merge pull request #17817 from rohitwaghchaure/fixed_pos_cash_payment_modal
fix: POS cash mode of payment css
2019-05-31 12:28:53 +05:30
Rohit Waghchaure
6f1e624465 fix: POS cash mode of payment css 2019-05-30 23:19:55 +05:30
deepeshgarg007
2dcd03d17d fix: Label translations 2019-05-30 22:33:02 +05:30
deepeshgarg007
ffcb7aa6ed fix: Add translations for missing labels in AR report 2019-05-30 22:26:52 +05:30
Rohit Waghchaure
9350b5a533 fix: allow import for packing slip 2019-05-30 21:52:13 +05:30
Nabin Hait
8cb2c7a89c fix: Set query for expense account in PO and PR 2019-05-30 18:13:11 +05:30
Nabin Hait
50bdaa6d1a fix: Added Expense Account field to push value from PO-PR-PI 2019-05-30 18:08:22 +05:30
Rohan Bansal
20a4cf1290 fix(selling): Remove Totals row for tree-based Sales Analytics 2019-05-30 17:24:19 +05:30
Suraj Shetty
fc092d0df4 Merge pull request #17807 from deepeshgarg007/gstr-1-condition-fix
fix: GSTR-1 report B2B condition fix
2019-05-30 17:24:04 +05:30
Rushabh Mehta
51bb2909c3 Merge pull request #17790 from deepeshgarg007/customer_lead_dashboard
fix: Customer and Lead dashboard fixes for opportunity and quotation
2019-05-30 17:21:25 +05:30
Suraj Shetty
cab0cd55b3 Merge branch 'hotfix' into gstr-1-condition-fix 2019-05-30 16:38:45 +05:30
deepeshgarg007
4f579639c6 fix: Use AND instead of OR 2019-05-30 16:26:38 +05:30
Nabin Hait
c5b68ef386 fix: Rounding adjustment while additional discount amount is aplied on grand total 2019-05-30 16:05:03 +05:30
deepeshgarg007
95dc4e4dc5 fix: Use make methods to override 2019-05-30 15:28:15 +05:30
Sahil Khan
dc35138356 Merge branch 'hotfix' 2019-05-30 12:09:35 +05:30
Sahil Khan
08617f7700 bumped to version 11.1.35 2019-05-30 12:29:35 +05:50
Anurag Mishra
cfecf3c5b1 fix: Added description if item variants does not have description in map (#17795)
* fix: variant item description based on attribute

* fix: requested changes

* fix: refactor
2019-05-29 17:16:48 +05:30
Shivam Mishra
831100b657 Merge pull request #17792 from adityahase/remove-manifest-hotfix
perf: Remove MANIFEST.in
2019-05-29 15:31:26 +05:30
Aditya Hase
f296a2f58a perf: Remove MANIFEST.in
Faster pip install -e erpnext

https://stackoverflow.com/questions/24727709/do-python-projects-need-a-manifest-in-and-what-should-be-in-it

https://github.com/frappe/frappe/pull/7360
2019-05-29 15:15:05 +05:30
deepeshgarg007
18a0120fc1 fix: Customer and Lead dashboard fixes for opportunity and quotation 2019-05-29 14:20:24 +05:30
Nabin Hait
aae557e8a1 Merge pull request #17779 from sunnyakaxd/patch-1
fix (performance): Dont fetch all orders to update a few
2019-05-29 10:04:37 +05:30
Nabin Hait
0f92c4b85b Merge pull request #17778 from deepeshgarg007/lead_owner
fix: Lead owner efficiency report query and column fixes
2019-05-29 09:57:08 +05:30
deepeshgarg007
217df1761d fix: Styling fixes 2019-05-29 08:10:07 +05:30
Himanshu Mishra
d355741462 Python 2 compatibility -_- 2019-05-28 23:54:03 +05:30
Himanshu Mishra
7b6ed4f16e Update status_updater.py 2019-05-28 23:51:22 +05:30
deepeshgarg007
c5a682e9d9 fix: Lead owner efficiency report query and column fixes 2019-05-28 23:40:05 +05:30
Sahil Khan
b4fa105555 Merge branch 'hotfix' 2019-05-28 14:50:05 +05:30
Sahil Khan
e1aef6f0db bumped to version 11.1.34 2019-05-28 15:10:05 +05:50
Nabin Hait
6f35d2b52d Merge pull request #17764 from nabinhait/salary-slip-tax-calc
fix: Tax calculation on salary slip
2019-05-28 11:16:40 +05:30
rohitwaghchaure
197f57c050 Merge pull request #17766 from rohitwaghchaure/renamed_delayed_item_report
fix: rename delayed order item report
2019-05-27 19:33:41 +05:30
Rohit Waghchaure
c74fa7546b fix: rename delayed order item report 2019-05-27 19:32:43 +05:30
Raffael Meyer
0261472ecd add default filters 2019-05-27 16:01:05 +02:00
Nabin Hait
233ef8752d Merge pull request #17550 from dimanex/bugfix/17547-Pricing-Rules-are-broken
Pricing Rules are not queried correctly after removing 'customer' and adding 'party_name' in Quotation #17547
2019-05-27 19:24:24 +05:30
Nabin Hait
afd9e7546f Merge branch 'hotfix' into bugfix/17547-Pricing-Rules-are-broken 2019-05-27 19:22:34 +05:30
Nabin Hait
8b1532d691 Merge pull request #17758 from saurabh6790/custom_field_fix_hotfix
fix: add shopify_supplier_id custom field while setting up shopify
2019-05-27 19:12:16 +05:30
Nabin Hait
a887c29e06 Merge pull request #17760 from nabinhait/multi-fixes99
fix: Error due to merging of lead/customer to party_name
2019-05-27 19:11:01 +05:30
Nabin Hait
7114b72be8 fix: Tax calculation on salary slip 2019-05-27 18:42:20 +05:30
Raffael Meyer
1c1a5958bc more pleasant icon color 2019-05-27 15:05:32 +02:00
Raffael Meyer
b7b5bcbd85 fix: em dash cannot be encoded in latin-1 2019-05-27 15:05:08 +02:00
Raffael Meyer
9638f0ef2b Add columns to CSV, add comments and docstrings 2019-05-27 14:42:52 +02:00
Nabin Hait
92ab345daf Merge pull request #17018 from chdecultot/fec_improvement
fix: Addition of third party types in FEC
2019-05-27 17:18:42 +05:30
Nabin Hait
79dd4d707b fix: Error fixed due to merging of lead/customer to party_name 2019-05-27 15:44:12 +05:30
Nabin Hait
a3a733fa91 fix: error because of non-mandatory fields 2019-05-27 15:43:26 +05:30
Nabin Hait
7a9b014f72 fix: Made item code non-mandatory in item 2019-05-27 15:41:06 +05:30
Saurabh
61b4a98356 fix: add shopify_supplier_id custom field while setting up shopify 2019-05-27 15:25:47 +05:30
Don-Leopardo
46db69b304 fix: Make from Lead to Opportunity (#17727)
* fix: lead to oportunity error

* fix: one more missmatched field
2019-05-27 14:22:52 +05:30
Joe Paul
a0be41322d fix(subscription): Remove property decorator (#17395) 2019-05-27 14:11:52 +05:30
Nabin Hait
39d30718e2 Merge branch 'hotfix' into copy_payment_schedule_from_quot_to_SO 2019-05-27 14:10:07 +05:30
Saif
05f29988f4 fix: Status updater for Credit/Debit Note Issued (#16998)
* fix: Status updater for Credit/Debit Note Issued higher precendence than Return

* style: linting
2019-05-27 14:05:14 +05:30
Deepesh Garg
d7903de51c fix: Do not fetch batch items and serialized items in stock reconciliation (#17726) 2019-05-27 13:41:58 +05:30
Kenneth Sequeira
0e31cc9ff8 improve error message (#17745)
Change ```Allocated amount can not greater than unadjusted amount```  to ```Allocated amount cannot be greater than unadjusted amount```

```Allocated amount can not be negative``` to ```Allocated amount cannot be negative```
2019-05-27 13:40:40 +05:30
rohitwaghchaure
32280a11aa fix: customer item code not fetched on selection of the item in the sales order (#17755) 2019-05-27 13:32:44 +05:30
Anurag Mishra
a2f9d2f89c fix: holidays was showing on same date in calendar view (#17753) 2019-05-27 13:20:06 +05:30
Nabin Hait
5fc5355b96 fix: Opening accounting entry for stock entry (#17710)
* fix: Opening accounting entry for stock entry

* test: Add test case for opening stock entry gle

* fix: validate expense account for opening stock entry

* fix: validate expense account for opening stock reco
2019-05-27 11:50:08 +05:30
Deepesh Garg
30c73e6b35 fix: Only show registered customers for GSTR-1 B2B Report (#17719) 2019-05-27 11:48:40 +05:30
Nabin Hait
7a6b88c791 fix: payment reconciliation against expense claim (#17728)
* feat: Added dashboard in expense claim

* fix: payment reconciliation against expense claim
2019-05-27 11:41:05 +05:30
rohitwaghchaure
9c42124fbc Merge pull request #17720 from rohitwaghchaure/reverting_method_to_show_stock_value
fix: warehouse tree view taking lot of time to load
2019-05-23 16:36:34 +05:30
Rohit Waghchaure
0378b15412 fix: warehouse tree view taking lot of time to load 2019-05-23 16:34:32 +05:30
rohitwaghchaure
3f86369604 fix: range 4 for ageing filter added in the AP/AR report (#17714) 2019-05-23 15:27:17 +05:30
rohitwaghchaure
cc99d92116 Merge pull request #17705 from rohitwaghchaure/not_able_to_submit_sales_invoice
fix: not able to submit sales invoice
2019-05-22 22:31:37 +05:30
Rohit Waghchaure
f880975438 fix: not able to submit sales invoice for italy 2019-05-22 22:30:26 +05:30
Saurabh
daa8db4d95 Merge branch 'hotfix' 2019-05-22 22:24:17 +05:30
Saurabh
9ff39e2d1b bumped to version 11.1.33 2019-05-22 22:54:17 +06:00
Saurabh
9d70c5d13f Merge pull request #17704 from rohitwaghchaure/typo_pos_not_working
fix: typo
2019-05-22 22:21:51 +05:30
Rohit Waghchaure
a9a82919e7 fix: typo 2019-05-22 22:15:01 +05:30
Sahil Khan
723ed07642 Merge branch 'hotfix' 2019-05-22 15:54:26 +05:30
Sahil Khan
86b531aea6 bumped to version 11.1.32 2019-05-22 16:14:26 +05:50
rohitwaghchaure
781a420593 Merge pull request #17702 from rohitwaghchaure/not_able_to_submit_sales_invoice_italy_localization
fix: italy localization, not able to submit sales invoice
2019-05-22 15:48:12 +05:30
Rohit Waghchaure
08f709c2a2 fix: italy localization, not able to submit sales invoice 2019-05-22 15:28:47 +05:30
Nabin Hait
a849f6e21e fix: update received qty in PO from PR and PI (#17692)
* fix: Don't set reqd date in PO based on MR, if less than today

* fix: update received qty in PO from PR

* fix: po status

* fix: set schedule date from MR to PO
2019-05-22 15:05:17 +05:30
rohitwaghchaure
6ff8387d56 Merge pull request #17679 from Anurag810/revert_change
fix(Revert): sales order status for order type 'Maintenance
2019-05-22 14:47:47 +05:30
rohitwaghchaure
2af9ff9c33 Merge pull request #17699 from rohitwaghchaure/italian_localization_issue_for_invoices
fix: removed translation for customer type and tax charge type
2019-05-22 13:21:20 +05:30
Rohit Waghchaure
01905cad2f fix: removed translation for customer type and tax charge type 2019-05-22 13:17:46 +05:30
Raffael Meyer
31f5055287 fix sql for multi-company case 2019-05-22 00:03:16 +02:00
Raffael Meyer
ce9239af83 fix error when downloading empty report 2019-05-21 22:49:59 +02:00
Raffael Meyer
50de88417c fix filename 2019-05-21 21:59:04 +02:00
Raffael Meyer
2701f94491 add remarks and voucher info 2019-05-21 21:58:35 +02:00
Anurag Mishra
58260e4f0a Merge branch 'hotfix' into revert_change 2019-05-21 16:52:01 +05:30
Anurag Mishra
a01869bb20 style: refactor 2019-05-21 16:50:20 +05:30
Anurag Mishra
3a92615f23 Merge branch 'revert_change' of https://github.com/anurag810/erpnext into revert_change 2019-05-21 14:15:58 +05:30
Sahil Khan
eca8db7405 Merge branch 'hotfix' 2019-05-21 14:11:08 +05:30
Sahil Khan
58c4cfc0d7 bumped to version 11.1.31 2019-05-21 14:31:08 +05:50
Anurag Mishra
ab52a4db75 fix: refactor sales_order_list.js 2019-05-21 13:09:47 +05:30
Saurabh
c8d3a8c0f5 Merge pull request #17686 from rohitwaghchaure/set_default_warehouse_from_the_stock_settings
fix: while making the item, default warehouse not set even if the stock settings has the default warehouse
2019-05-21 12:52:51 +05:30
rohitwaghchaure
aab88eee3e Merge pull request #17644 from nabinhait/bom-item-rate
fix: BOM Item rate based on uom conversion factor and exchange rate
2019-05-21 12:25:19 +05:30
Rushabh Mehta
d9f4c83567 Merge pull request #17539 from adityahase/fix-training-feedback-hotfix
fix(hr): Use event_status instead of status
2019-05-21 12:20:29 +05:30
Rushabh Mehta
b96dd366ce Merge pull request #17641 from nabinhait/gle-opening-stock-reco
fix: GL Entry for opening stock reconciliation
2019-05-21 12:17:04 +05:30
rohitwaghchaure
597ec83af7 Merge pull request #17684 from rohitwaghchaure/item_group_not_disaplying_in_website
fix: item group not disaplying in the website if shopping cart is disabled
2019-05-21 12:15:39 +05:30
Rohit Waghchaure
e802bdd186 fix: while making the item, default warehouse not set even if the stock settings has the warehouse 2019-05-21 12:11:40 +05:30
Rohit Waghchaure
3a949bb298 fix: item group not disaplying in the website if shopping cart is disabled 2019-05-21 10:18:39 +05:30
Raffael Meyer
13c9d041d9 Merge branch 'hotfix' of https://github.com/frappe/erpnext into datev_report 2019-05-21 00:33:45 +02:00
rohitwaghchaure
1e920dd0d8 Merge pull request #17681 from rohitwaghchaure/expense_claim_reconciliation_issue
fix: payment reconciliation not update the status of the expense claim
2019-05-20 22:41:48 +05:30
Rohit Waghchaure
09536f402e fix: payment reconciliation not update the status of the expense claim 2019-05-20 17:01:22 +05:30
Anurag Mishra
581f26b7a0 Merge branch 'hotfix' into revert_change 2019-05-20 16:22:20 +05:30
Deepesh Garg
0418a2f70a Merge pull request #17677 from rohitwaghchaure/show_opening_entries_gl_report
feat: added checkbox in the filter of general ledger to show opening entries
2019-05-20 15:21:28 +05:30
Saurabh
5e3338744c Merge pull request #17675 from nabinhait/lead-from-email
fix: Person / Org name is not mandatory while creation of lead from email
2019-05-20 14:57:16 +05:30
Anurag Mishra
da3762700c fix(Revert): sales order status for order type 'Maintenance 2019-05-20 12:38:33 +05:30
Rohit Waghchaure
2c9fccd8ba feat: added checkbox in the filter of general ledger to show opening entries 2019-05-20 12:25:53 +05:30
Nabin Hait
286c4fa640 fix: Person / Org name is not mandatory while creation of lead from email 2019-05-20 12:16:34 +05:30
Deepesh Garg
a144e002db Merge pull request #17667 from deepeshgarg007/quotation-qty-fix
fix: Quotation to lead fix while changing item qty
2019-05-18 23:38:24 +05:30
deepeshgarg007
553dabaa08 fix: Pricing rule fix for lead 2019-05-18 21:31:58 +05:30
Anurag Mishra
55d0d32c77 fix: Allow return if delivery note or sales order is required in selling settings(v11) (#17632)
* fix: Allow retrun if delivery note or sales order is required in selling settings

* fix: combined condition

* style: refactor
2019-05-18 13:02:31 +05:30
Deepesh Garg
1f93745eef Merge pull request #17663 from deepeshgarg007/opportunity-list-fixes
fix: Opportunity List view fix
2019-05-17 19:36:08 +05:30
deepeshgarg007
e3a02dd5f6 Merge branch 'hotfix' of https://github.com/frappe/erpnext into opportunity-list-fixes 2019-05-17 19:11:13 +05:30
deepeshgarg007
153733414f fix: Opportunity List view fix 2019-05-17 19:08:24 +05:30
Deepesh Garg
ac535f0ce9 Merge pull request #17661 from deepeshgarg007/quotation_lead_fixes
fix: Quotation to lead fix
2019-05-17 18:35:49 +05:30
deepeshgarg007
3886529787 fix: Get lead details only if lead name entered 2019-05-17 18:10:13 +05:30
Deepesh Garg
d2cd713b89 Merge pull request #17657 from deepeshgarg007/territory_item_code_hotfix
fix: Inactive Sales Item report fixes
2019-05-17 15:41:50 +05:30
Deepesh Garg
6b378e1669 fix: Unable to create item variant based on manufacturer (#17651)
* fix: Unable to create item variant against manufacturer

* fix: Spacing fixes

* fix: Spacing fixes in item.js
2019-05-17 15:39:59 +05:30
deepeshgarg007
a4fc30bbe4 fix: Inactive Sales Item report fixes 2019-05-17 15:39:23 +05:30
rohitwaghchaure
b4b0e4424d Merge pull request #17655 from rohitwaghchaure/not_able_to_make_si_from_dn
fix: not able to make si from dn
2019-05-17 15:29:04 +05:30
Rohit Waghchaure
f3bdcc2a84 fix: not able to make si from dn 2019-05-17 15:28:12 +05:30
Nabin Hait
19901c14c9 fix: Removed unused variable 2019-05-17 14:30:45 +05:30
Deepesh Garg
714d686e50 Merge pull request #17650 from deepeshgarg007/gstr2_fix
fix: GSTR 2 report fix
2019-05-17 11:24:44 +05:30
rohitwaghchaure
094dc1dee6 Merge pull request #17646 from rohitwaghchaure/fixed_bank_reco_internal_transfer
fix: bank reconciliation for internal transfer is not working
2019-05-17 11:20:43 +05:30
deepeshgarg007
cdcf424ba5 Merge branch 'hotfix' of https://github.com/frappe/erpnext into gstr2_fix 2019-05-17 10:30:39 +05:30
deepeshgarg007
2a2b884e32 fix: Return taxable value in get_row_data_for_invoice 2019-05-17 10:20:14 +05:30
Rohit Waghchaure
c1e00f4daa fix: bank reconciliation for internal transfer is not working 2019-05-17 00:01:21 +05:30
Rohan
0a22aab6bb fix(tests): Save batch instead of submitting it (#17636) 2019-05-16 19:45:11 +05:30
Nabin Hait
43c6d1a518 fix: Gte lead details in opportunity (#17633) 2019-05-16 19:35:27 +05:30
Nabin Hait
090219814e fix: BOM Item rate based on uom conversion factor and exchange rate 2019-05-16 19:17:02 +05:30
Nabin Hait
510dc60bf0 fix: GL Entry for opening stock reconciliation 2019-05-16 17:28:39 +05:30
Saurabh
12d520a366 Merge pull request #17562 from fproldan/fix_bundlestock
fix: Available Stock for Packing Items error
2019-05-16 15:40:02 +05:30
Saurabh
a06a527fe6 Merge pull request #17629 from nabinhait/multi-fixes-33
fix: Multiple small fixes
2019-05-16 15:39:31 +05:30
Rushabh Mehta
9a7681535f Merge pull request #17634 from nabinhait/add-multiple-items
feat: Added 'Add Multiple' options in all sales / purchase transactions
2019-05-16 14:56:44 +05:30
Nabin Hait
8e1a612b3b feat: Added 'Add Multiple' options in all sales / purchase transactions 2019-05-16 14:48:10 +05:30
Deepesh Garg
21085bf2be fix: Query fixes in quotation and opportunity (#17619)
* fix: Query fixes for contact person and minor fixes

* fix: Change quotation to quotation_to
2019-05-16 14:11:21 +05:30
Anurag Mishra
8e9413829d fix: variant item description based on attribute (#17627)
* fix: variant item description based on attribute

* fix: requested changes

* style: removed print
2019-05-16 13:57:35 +05:30
Nabin Hait
8208f878ff fix: show tasks in project order by due date and status 2019-05-16 13:43:08 +05:30
Nabin Hait
a7130649cd fix: Get bank account on selection of payment mode in Loan 2019-05-16 13:43:07 +05:30
Nabin Hait
b2d9ffa4ca fix: To allow creation of sales invoice without customer 2019-05-16 13:43:07 +05:30
Himanshu
cc4f13a862 validate: check additional salary component exists (#17530) 2019-05-16 10:34:46 +05:30
Saurabh
60681baf80 Merge branch 'hotfix' into fix_bundlestock 2019-05-15 15:28:58 +05:30
Saurabh
ea6049078a Merge pull request #17620 from rohitwaghchaure/auto_set_the_barcode_if_item_has_one_barcode
fix: set barcode on selection of item if item has one barcode
2019-05-15 15:09:51 +05:30
Rohit Waghchaure
d83e8c56b2 fix: set barcode on selection of item if item has one barcode 2019-05-15 14:10:10 +05:30
Deepesh Garg
e0ade62e38 fix: Status updater fixes in PO and SO and test coverage for return (#17490)
* fix: Status updator fixes in sales and purchase cycle

* fix: Test cases for return in so and po
2019-05-15 12:18:12 +05:30
bghayad
c78b921412 Fix for Chart of Account sorting problem (#17563)
* First Commit from Master

* Fix for CoA sorting problem

* Fixing for CoA sorting problem

* Fix for Chart of Account Sorting Problem
2019-05-15 11:58:59 +05:30
Palash Jhabak
9e9e415c5f fix: Cancelled Lab Tests shouldnt show in SI (#17616)
Cancelled Lab Tests were also showing up in Get Items of SI

fixes issue #17607
2019-05-15 11:37:31 +05:30
Saurabh
0692e5eb78 Merge branch 'hotfix' 2019-05-15 08:07:29 +05:30
Saurabh
3fa5eec07b bumped to version 11.1.30 2019-05-15 08:37:29 +06:00
rohitwaghchaure
ab1bf1af19 fix: not able to create the sales invoice without item code (#17610) 2019-05-15 07:45:47 +05:30
sahil28297
15e0861e82 fix(patch): set attribute to none if it does not exist (#17605) 2019-05-15 07:44:45 +05:30
Prasad Ramesh
aa493a25f8 fix: made Sales Partner Comission report visible in Selling module (#17604) 2019-05-15 07:43:39 +05:30
Saurabh
1c2915f74b fix: reload docs before creating custom fields (#17585) 2019-05-15 07:43:16 +05:30
rohitwaghchaure
391b3b67cb fix: limit offset was missing in the get_delivery_notes_to_be_billed method (#17609) 2019-05-15 07:41:10 +05:30
Nabin Hait
0361c50503 refactor: Payroll processing and tax calculation (#17595)
* refactor: Payroll processing and tax calculation

* fix: payroll test cases

* fix: Codacy fixes

* fix: removed debug mode

* fix: payroll test cases

* Update payroll_period.py
2019-05-15 07:38:57 +05:30
Sahil Khan
517a3071cf Merge branch 'hotfix' 2019-05-14 16:48:26 +05:30
Sahil Khan
0e30e705c5 bumped to version 11.1.29 2019-05-14 17:08:26 +05:50
Deepesh Garg
940df7563b Merge pull request #17575 from deepeshgarg007/quotation-filter-fixes
fix: Standard filter and dashboard fixes in quotation and opportunity
2019-05-14 15:10:41 +05:30
deepeshgarg007
f390872944 Merge branch 'hotfix' of https://github.com/frappe/erpnext into quotation-filter-fixes 2019-05-14 14:58:22 +05:30
deepeshgarg007
cfd18d4e03 fix: Lead and customer dashboard fixes 2019-05-14 14:57:22 +05:30
Deepesh Garg
6c73439e7f Merge pull request #17598 from deepeshgarg007/lead-fixes
fix: Change lead to party_name in Lead
2019-05-14 14:41:49 +05:30
deepeshgarg007
2389e2c438 fix: Change lead to party_name 2019-05-14 14:40:18 +05:30
Deepesh Garg
c2341ca8e3 Merge pull request #17596 from deepeshgarg007/territory_group_fixes_hotfix
fix: Make territory filter mandatory
2019-05-14 14:35:26 +05:30
deepeshgarg007
3b810ea8da fix: Make territory filter mandatory 2019-05-14 14:32:36 +05:30
Deepesh Garg
f85d6aeecd Merge pull request #17589 from deepeshgarg007/inactive_items_row_hotfix
fix: Do not append row if item is sold within days since last ordered
2019-05-14 11:56:41 +05:30
rohitwaghchaure
a13762b05f Merge pull request #17581 from saurabh6790/quoation_creation_fix
fix: validate customer while pulling information
2019-05-14 11:51:15 +05:30
rohitwaghchaure
dd5a0a1f26 Merge pull request #17545 from rohitwaghchaure/incorrect_payment_amount_if_advance_amount_in_si
fix: incorrect payment amount in the payment terms if the sales invoice has the advance amount
2019-05-14 11:14:55 +05:30
deepeshgarg007
a6ad0b0ec8 fix: Do not append row if item is sold within days since last order 2019-05-14 08:49:24 +05:30
Saurabh
077e20f7ae fix: valiadte customer while pulling information 2019-05-13 15:21:25 +05:30
Saurabh
73c6d2e44c Merge pull request #17555 from Alchez/hotfix-lead-import-fix
feat(crm): Allow leads to be imported without person name
2019-05-13 13:07:04 +05:30
Saurabh
d7a13ceb10 Merge pull request #17568 from Mangesh-Khairnar/event-fix
feat(training-event): validate event period
2019-05-13 13:06:17 +05:30
Saurabh
6eadd6657d Merge pull request #17574 from rohitwaghchaure/delayed_orders_summary_report
feat: delayed order summary report
2019-05-13 13:05:40 +05:30
Saurabh
0c890a110d Merge branch 'hotfix' into hotfix-lead-import-fix 2019-05-13 12:07:33 +05:30
Saurabh
0f420baaba Merge branch 'hotfix' into event-fix 2019-05-13 11:46:29 +05:30
Aditya Hase
b32d96fc24 fix(accounts): Add missing field (#17571) 2019-05-13 10:21:41 +05:30
Suraj Shetty
cfc9e18749 Merge pull request #17532 from surajshetty3416/fix-rename-account
fix: Show "Merge Account" button only to users with write access
2019-05-13 10:03:16 +05:30
Rohan
7178218821 Merge branch 'hotfix' into hotfix-shipping-override 2019-05-12 22:28:45 +05:30
Deepesh Garg
25d6d08329 Merge pull request #17576 from deepeshgarg007/territory_items_hotfix
fix: Show all territories and items in inactive sales item report
2019-05-12 20:44:06 +05:30
Deepesh Garg
9bf4c754c8 Merge branch 'hotfix' into territory_items_hotfix 2019-05-12 18:40:54 +05:30
deepeshgarg007
79b02db156 fix: Indentation fixes 2019-05-12 18:27:52 +05:30
Rohit Waghchaure
e55dd7233d feat: delayed order summary report 2019-05-12 17:17:55 +05:30
rohitwaghchaure
3ba969ad58 Merge pull request #17573 from adityahase/fix-lead-make-quotation
fix(lead): Map lead name to quotation party_name
2019-05-12 17:10:14 +05:30
rohitwaghchaure
f93cb0a6ba Merge pull request #17567 from rohitwaghchaure/fixed_multiple_bank_reconciliation_issues
fix: fixed multiple bank reconciliation issues
2019-05-12 17:04:58 +05:30
Aditya Hase
e23cfd22ca fix(lead): Map lead name to quotation party_name 2019-05-12 16:20:31 +05:30
Raffael Meyer
9eef60754d remove unused import 2019-05-12 02:24:39 +02:00
Mangesh-Khairnar
0d1b022ea0 feat(training-event): validate event period 2019-05-11 23:30:52 +05:30
deepeshgarg007
aca3772f7d fix: Show all territories and items in inactive sales item report 2019-05-11 21:12:51 +05:30
deepeshgarg007
569815b5ad fix: Standard filter and dashboard fixes in quotation and opportunity 2019-05-11 20:09:29 +05:30
Rohit Waghchaure
80b696ce25 fix: wrong journal entries are showing in the reconcilliation section 2019-05-11 14:58:25 +05:30
rohitwaghchaure
ab7570b7e5 Merge pull request #17558 from rohitwaghchaure/incorrect_stock_balance_showing_in
fix: incorrect stock balance showing in the warehouse tree view
2019-05-11 11:30:24 +05:30
NahuelOperto
c87f8c6f00 fix codecay 2019-05-10 10:46:41 -03:00
Rohit Waghchaure
c5c4de885b fix: bank reconciliation not showing as Settled instead of Reconciled 2019-05-10 19:08:41 +05:30
NahuelOperto
a970bcc56d fix identation 2019-05-10 09:17:52 -03:00
NahuelOperto
5e2d822509 fix error when the product bundle does not have the original item name 2019-05-10 09:00:46 -03:00
Rohit Waghchaure
6be1475882 fix: incorrect stock balance showing in the warehouse tree view 2019-05-10 17:19:50 +05:30
Rohan Bansal
43f05d1de1 feat(crm): Allow leads to be imported without person name 2019-05-10 16:03:16 +05:30
rohitwaghchaure
26bb028ec4 Merge pull request #17549 from sunhoww/pos_batch
fix: POS batch not set correctly
2019-05-10 14:14:44 +05:30
Rohit Waghchaure
1637f0aeaf fix: test cases 2019-05-10 13:42:38 +05:30
Saurabh
353f64caf8 Merge pull request #17541 from rohitwaghchaure/project_update_statue_emails_sending_frequestly
fix: project update status emails are sent frequently
2019-05-10 13:24:24 +05:30
Saurabh
5afb00a7f4 Merge branch 'hotfix' into fix-rename-account 2019-05-10 12:40:00 +05:30
Saurabh
b0ec0f545e Merge pull request #17540 from surajshetty3416/fix-slow-item-search
perf: Index show_in_website field for faster item search
2019-05-10 12:38:06 +05:30
rohitwaghchaure
7088513da9 Update project.py 2019-05-10 12:04:21 +05:30
Mohammad Noureldin
8908d4ee8f 17547:
- Filling in 'customer' arg field if not already set and if 'party_name' is available
- This will fix the logic during which Pricing Rule is constructing the SQL query to list all Pricing Rules related to an item
- The reason to put it in accounts_controller is:
-# This is the palce when args are made before making call which will end using Pricing Rule logic, which means we don't have to go all over the place to add the proper arg field
-# IMHO, it is clean enough in contrast to the case where that code is added to pricing_rule.py for example, cause doing this exposes Pricing Rule to the knowledge about a field called 'party_name' while a Pricing Rule document doesn't have any
2019-05-09 18:21:32 +02:00
Sun Howwrongbum
8133970944 fix: POS batch not set correctly 2019-05-09 20:45:19 +05:30
Rohit Waghchaure
dac7ede911 fix: incorrect payment amount in the payment terms if the sales invoice has the advance amount 2019-05-09 19:50:00 +05:30
Rohit Waghchaure
b052498348 fix: project update status emails sent frequently 2019-05-09 19:04:58 +05:30
Aditya Hase
d62de6c8e5 fix(hr): Use event_status instead of status
Training Feedback DocType has event_status field (not status)
This was broken since PR #10379, PR #17197 made this failure explicit.
2019-05-09 19:01:00 +05:30
Suraj Shetty
d37cc9a5d0 perf: Index show_in_website field for faster item search 2019-05-09 18:49:57 +05:30
Suraj Shetty
c7062d8be7 fix: Check permissions before renaming the account 2019-05-09 14:18:41 +05:30
Suraj Shetty
1435e30ad5 fix: Show "Merge Account" button only to users with write access 2019-05-09 14:16:49 +05:30
Raffael Meyer
3799aabc46 Merge branch 'hotfix' of https://github.com/frappe/erpnext into datev_report 2019-05-09 04:04:33 +02:00
Raffael Meyer
4b2901704c Add download button 2019-05-09 04:03:23 +02:00
Raffael Meyer
e5f7af9e9f Use pandas, more columns, filter by date 2019-05-09 03:54:49 +02:00
Anurag Mishra
6fc136fcb8 Merge branch 'hotfix' into copy_payment_schedule_from_quot_to_SO 2019-05-08 23:07:31 +05:30
rohitwaghchaure
b2ff0bda32 Merge pull request #17526 from rohitwaghchaure/allow_data_import_for_salary_slip
fix: allow data import for salary slip
2019-05-08 22:20:20 +05:30
Rohit Waghchaure
ff42d7b5ed fix: allow data import for salary slip 2019-05-08 20:17:47 +05:30
Anurag Mishra
35a4cae2f6 feat: Adding action Stop or Warn for Quality inspection if it is not submitted
* feat: added action on quality inspection

* feat: added action on quality inspection

* feat: Allow the user to by pass inspection if action is warn ad stop when action is to warn

* patch: for setting default action to 'Stop'

* fix: resolve conflicts

* fix: travis

* Update stock_controller.py
2019-05-08 17:41:04 +05:30
rohitwaghchaure
a76cafecb0 Merge pull request #17521 from rohitwaghchaure/fixed_get_invoiced_item_gross_margin
fix: get totals of gross profit amount on call of the method get_invoiced_item_gross_margin
2019-05-08 16:17:11 +05:30
rohitwaghchaure
715ecc31c8 Merge pull request #17519 from rohitwaghchaure/added_validation_for_stock_entry_purpose
fix: job card issue, added validation in the stock entry
2019-05-08 16:16:39 +05:30
deepeshgarg007
09145674ec bumped to version 11.1.28 2019-05-08 15:58:50 +05:50
Rohit Waghchaure
11eebddb79 fix: get totals of gross profit amount on call of the method get_invoiced_item_gross_margin 2019-05-08 15:31:29 +05:30
Rohit Waghchaure
7d7417af29 fix: job card issue, added validation in the stock entry 2019-05-08 15:07:31 +05:30
rohitwaghchaure
6edb6e0b09 Merge pull request #17506 from Anurag810/rename_column
fix: renamed column avg. buying rate to valuation rate in gross profit report
2019-05-08 14:34:14 +05:30
rohitwaghchaure
e057575661 Merge pull request #17518 from rohitwaghchaure/customer_not_able_to_save
fix: not able to save customer if contribution is not set
2019-05-08 14:33:44 +05:30
Rohit Waghchaure
b7b5eeb92b fix: not able to save customer 2019-05-08 14:28:33 +05:30
rohitwaghchaure
85731053fd Merge pull request #17514 from rohitwaghchaure/pricing_rule_not_working_on_quotation
fix: pricing rule not working properly on the quotation
2019-05-08 11:14:34 +05:30
Rohit Waghchaure
9f3eb9e077 fix: pricing rule not working properly on the quotation 2019-05-08 11:13:56 +05:30
Sahil Khan
5ac8dbfceb Merge branch 'hotfix' 2019-05-07 17:55:28 +05:30
Sahil Khan
f4f2301e5b bumped to version 11.1.27 2019-05-07 18:15:28 +05:50
rohitwaghchaure
7888336524 Merge pull request #17512 from rohitwaghchaure/address_not_set_from_the_lead
fix: address not set on the quotation from the lead
2019-05-07 17:50:09 +05:30
Rohit Waghchaure
b8c2e02c67 fix: address not set on the quotation from the lead 2019-05-07 17:18:00 +05:30
Sahil Khan
a9e9efbd23 Merge branch 'hotfix' 2019-05-07 14:45:45 +05:30
Sahil Khan
2f175e6d85 bumped to version 11.1.26 2019-05-07 15:01:01 +05:50
rohitwaghchaure
df817a858b Merge pull request #17510 from rohitwaghchaure/fixed_lead_dashbord_quotation_redirect
fix: quotation link in the lead dashboard not working and filter from the dashboard was not set in the list view
2019-05-07 14:30:16 +05:30
Rohit Waghchaure
4a73059ed3 fix: quotation link in the lead dashboard not working and filter from the dashboard was not applying 2019-05-07 14:29:39 +05:30
rohitwaghchaure
552615525c Merge pull request #17511 from deepeshgarg007/quotation-refactor-fixes
fix: Dynamic Link fieldname fix in quotation
2019-05-07 14:25:38 +05:30
deepeshgarg007
25e408fd2a fix:Contact person query fix in quotation 2019-05-07 12:43:20 +05:30
rohitwaghchaure
375a6f67ae Merge pull request #17505 from rohitwaghchaure/customer_not_found_in_qtn
fix: not able to make sales order from the lead quotation
2019-05-06 19:26:24 +05:30
Anurag Mishra
01095799e8 fix: renamed column avg. buying rate to valuation rate 2019-05-06 17:41:28 +05:30
Rohit Waghchaure
ead8d82a84 fix: not able to make sales order from the lead quotation 2019-05-06 17:16:57 +05:30
Deepesh Garg
2c229c6403 Merge pull request #17495 from sagarvora/ewb_fixes
fix(regional): imporvements to e-Way Bill JSON generation
2019-05-06 12:31:31 +05:30
Sagar Vora
5fb78a375d fix(regional): imporvements to e-Way Bill JSON generation
- Set pincode correctly in 'Bill To - Ship To' scenario
- Python 2 compatibility (convert to int after rounding)
- Avoid execeeding max character limit in tax amounts by rounding the same to two digits
2019-05-06 11:32:37 +05:30
Tyler Matteson
8fcad571f5 Batch naming series hotfix (#17483)
* fix: not able to make sales order from quotation

* fix: batch naming series unicode() call is py3 incompatible
2019-05-04 23:49:24 +05:30
Himanshu
53d7e667dd fix: patch to remove scheduling tool (#17472)
* fix: patch to remove scheduling tool

* fix: drop table

* patch: delete table if exists

* fix: remove drop table

* use orm
2019-05-04 22:42:35 +05:30
Rohan
7395716476 fix(stock): Allow expired batches to be flushed out of the system (#17477) 2019-05-04 22:40:42 +05:30
Rushabh Mehta
c068b6a885 fix: unlink task rather than deleting it (#17486) 2019-05-04 22:39:00 +05:30
Himanshu Warekar
02d28c5908 fix: use list comprehension 2019-05-04 22:35:08 +05:30
Rohan
90d0d24d1a Update erpnext/selling/doctype/customer/customer.py
Co-Authored-By: hrwX <himanshuwarekar@yahoo.com>
2019-05-04 22:35:08 +05:30
Himanshu Warekar
6aab14f9cf fix: calculate percentage only if sales team exist 2019-05-04 22:35:08 +05:30
Himanshu Warekar
163dbdca34 fix: allocated percentage should be equal to 100 2019-05-04 22:35:08 +05:30
Himanshu Warekar
dcc99a2644 fix: python side validation 2019-05-04 22:35:08 +05:30
Saurabh
f94951a51b Merge branch 'hotfix' into copy_payment_schedule_from_quot_to_SO 2019-05-03 16:48:14 +05:30
Rohit Waghchaure
f5297cf386 fix: not able to make sales order from quotation 2019-05-03 15:52:59 +05:30
Mangesh-Khairnar
9f7fd16882 feat: unlink task from project on task deletion 2019-05-03 13:06:19 +05:30
Nabin Hait
5296ab1f87 Merge pull request #16783 from sahil28297/default_warehouse_for_sales_return
fix: set warehouse from def_warehouse_for_sales_return in sales return
2019-05-03 09:27:04 +05:30
Nabin Hait
e42c14f2cb Merge pull request #17469 from rohitwaghchaure/fixed_sales_order_issue_from_quotation
fix: not able to make sales order from quotation
2019-05-03 09:19:27 +05:30
Rohit Waghchaure
4ef10fd6c3 fix: not able to make sales order from quotation 2019-05-03 01:48:45 +05:30
sahil28297
4c0d0e226b Merge branch 'hotfix' into default_warehouse_for_sales_return 2019-05-03 00:05:22 +05:30
Deepesh Garg
094caaa03e Merge pull request #17465 from deepeshgarg007/inactive-items-fix-hotfix
fix: Inactive sales item report fix
2019-05-02 23:50:57 +05:30
Nabin Hait
ce51553d29 Merge pull request #16907 from sagarvora/ewb
feat(regional 🇮🇳): auto-generate e-Way Bill JSON from Sales Invoice
2019-05-02 21:55:24 +05:30
Nabin Hait
f41fc21274 Merge branch 'hotfix' into ewb 2019-05-02 21:54:38 +05:30
Nabin Hait
1f49b77529 Merge pull request #17460 from nabinhait/project-billing-summary
Refactor: Project billing summary Report
2019-05-02 21:48:35 +05:30
deepeshgarg007
a0012f8c48 fix: Inactive sales item report fix 2019-05-02 19:32:43 +05:30
Nabin Hait
4b1c3ad7ac refactor: Project and billing summary 2019-05-02 18:11:27 +05:30
Anurag Mishra
a063803224 fix: handling case if from date and to date are equal in billing reports 2019-05-02 18:11:27 +05:30
Saurabh
63c7fd90a5 Merge branch 'hotfix' 2019-05-02 16:58:24 +05:30
Saurabh
c9c02c7c85 bumped to version 11.1.25 2019-05-02 17:28:24 +06:00
Nabin Hait
bc7ef1937e Merge pull request #17455 from saurabh6790/multiple_fixes
fix: data pulling based on quotation_to and party_name
2019-05-02 16:01:07 +05:30
Nabin Hait
75b63c5b4c Update set_missing_title_for_quotation.py 2019-05-02 16:00:49 +05:30
Saurabh
625191d20a fix: provision to setup customer name on quotation save and patch for the same 2019-05-02 15:50:01 +05:30
Saurabh
1417c7e828 fix: data pulling based on quotation_to and party_name 2019-05-02 14:12:29 +05:30
Saurabh
a4bbc68945 Merge pull request #17449 from nabinhait/auto-account-creation-company-tree
fix: Validate parent account of child company while creating new account based on parent company
2019-05-02 12:26:23 +05:30
Nabin Hait
2d7a591c61 Merge branch 'hotfix' into auto-account-creation-company-tree 2019-05-02 09:56:53 +05:30
Nabin Hait
9ef79d6c6b Merge branch 'hotfix' into copy_payment_schedule_from_quot_to_SO 2019-05-02 01:00:04 +05:30
Nabin Hait
448a5e1c9c Merge pull request #17447 from nabinhait/woocommerce-multilingual-fix
fix: Multilingual handling in woocommerce integration
2019-05-01 21:15:07 +05:30
Nabin Hait
7be75adc3f fix: Validate parent account of child company while creating new account based on parent company 2019-05-01 20:26:09 +05:30
Nabin Hait
fafee7cf61 Merge pull request #17442 from nabinhait/work-order-bom-image
feat: Added item image in work order and bom
2019-05-01 19:31:24 +05:30
Nabin Hait
16aa23e454 fix: Multilingual handling in woocommerce integration 2019-05-01 19:17:59 +05:30
Nabin Hait
a4d5c5414d Merge pull request #17440 from nabinhait/pe-ref-exchange-rate
fix: Always fetch exchange rate from ref document
2019-05-01 17:17:46 +05:30
Nabin Hait
b104e3595c feat: Added item image in work order and bom 2019-05-01 16:37:32 +05:30
Deepesh Garg
5a06dd1ed1 Merge pull request #17436 from deepeshgarg007/name_fix_hotfix
fix: Rename Inactive Items report to Inactive Sales Items
2019-05-01 16:29:02 +05:30
Nabin Hait
27fe55efe1 fix: Always fetch exchange rate from ref document 2019-05-01 15:32:30 +05:30
Deepesh Garg
d29fde0bf3 Merge branch 'hotfix' into name_fix_hotfix 2019-05-01 14:27:17 +05:30
deepeshgarg007
8326925fe8 fix: Rename Inactive Items report to Inactive Sales Item 2019-05-01 13:36:08 +05:30
Deepesh Garg
09ac547a80 Merge branch 'hotfix' into ewb 2019-04-30 10:28:57 +05:30
deepeshgarg007
0555223797 Merge branch 'hotfix' of https://github.com/frappe/erpnext into ewb 2019-04-28 23:22:48 +05:30
deepeshgarg007
de93efb304 fix: Added test cases for ewb json creation 2019-04-28 23:14:02 +05:30
deepeshgarg007
6856033d3c fix: Code cleanup and fixes 2019-04-28 23:13:26 +05:30
ashish-greycube
e82ab87f1c fix: copy_payment_schedule_from_quot_to_SO 2019-04-26 12:12:53 +05:30
Sagar Vora
4dacb89da6 fix: test case and semicolons 2019-04-25 21:45:26 +05:30
Sagar Vora
c552d74746 fix: add missing semicolons 2019-04-25 21:45:26 +05:30
Sagar Vora
2697c2d869 feat(regional | India): auto-generate e-Way Bill JSON from Sales Invoice 2019-04-25 21:45:26 +05:30
Raffael Meyer
9c923ae418 feat(regional): Report for german tax consultants (DATEV) 2019-04-25 01:09:56 +02:00
Nabin Hait
8fd90410f1 Merge branch 'hotfix' into hotfix-shipping-override 2019-04-11 11:46:56 +05:30
Nabin Hait
f62e789173 Merge branch 'hotfix' into fec_improvement 2019-04-11 11:46:43 +05:30
Charles-Henri Decultot
91578757ff Addition of third party types in FEC 2019-03-26 08:57:36 +00:00
Rohan Bansal
eac87b4764 fix(transaction): Avoid shipping rule charge override by tax template 2019-03-11 15:02:39 +05:30
Sahil Khan
88bd0674ed fix: set warehouse from defalut_warehouse_for_sales_return in sales return 2019-02-26 14:50:20 +05:30
263 changed files with 13059 additions and 9403 deletions

View File

@@ -3,6 +3,11 @@ dist: trusty
python:
- "2.7"
- "3.6"
env:
- TEST_TYPE="Server Side Test"
- TEST_TYPE="Patch Test"
services:
- mysql
@@ -39,18 +44,8 @@ before_script:
- bench start &
- sleep 10
jobs:
include:
- stage: test
script:
- set -e
- bench run-tests --app erpnext --coverage
after_script:
- coveralls -b apps/erpnext -d ../../sites/.coverage
env: Server Side Test
- # stage
script:
- wget http://build.erpnext.com/20171108_190013_955977f8_database.sql.gz
- bench --force restore ~/frappe-bench/20171108_190013_955977f8_database.sql.gz --mariadb-root-password travis
- bench migrate
env: Patch Testing
script:
- bash $TRAVIS_BUILD_DIR/travis/run-tests.sh
after_script:
- coveralls -b apps/erpnext -d ../../sites/.coverage

View File

@@ -1,20 +0,0 @@
include MANIFEST.in
include requirements.txt
include *.json
include *.md
include *.py
include *.txt
include .travis.yml
recursive-include erpnext *.txt
recursive-include erpnext *.css
recursive-include erpnext *.csv
recursive-include erpnext *.html
recursive-include erpnext *.ico
recursive-include erpnext *.js
recursive-include erpnext *.json
recursive-include erpnext *.md
recursive-include erpnext *.png
recursive-include erpnext *.py
recursive-include erpnext *.svg
recursive-include erpnext/public *
recursive-exclude * *.pyc

View File

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

View File

@@ -42,15 +42,14 @@ frappe.ui.form.on('Account', {
// show / hide convert buttons
frm.trigger('add_toolbar_buttons');
}
frm.add_custom_button(__('Update Account Name / Number'), function () {
frm.trigger("update_account_number");
});
}
if(!frm.doc.__islocal) {
frm.add_custom_button(__('Merge Account'), function () {
frm.trigger("merge_account");
});
if (frm.has_perm('write')) {
frm.add_custom_button(__('Update Account Name / Number'), function () {
frm.trigger("update_account_number");
});
frm.add_custom_button(__('Merge Account'), function () {
frm.trigger("merge_account");
});
}
}
},
account_type: function (frm) {

View File

@@ -105,20 +105,27 @@ class Account(NestedSet):
descendants = get_descendants_of('Company', self.company)
if not descendants: return
acc_name_map = {}
acc_name = frappe.db.get_value('Account', self.parent_account, "account_name")
parent_acc_name_map = {}
parent_acc_name = frappe.db.get_value('Account', self.parent_account, "account_name")
for d in frappe.db.get_values('Account',
{"company": ["in", descendants], "account_name": acc_name},
{"company": ["in", descendants], "account_name": parent_acc_name},
["company", "name"], as_dict=True):
acc_name_map[d["company"]] = d["name"]
parent_acc_name_map[d["company"]] = d["name"]
if not acc_name_map: return
if not parent_acc_name_map: return
for company in descendants:
if not parent_acc_name_map.get(company):
frappe.throw(_("While creating account for child Company {0}, parent account {1} not found. Please create the parent account in corresponding COA")
.format(company, parent_acc_name))
doc = frappe.copy_doc(self)
doc.flags.ignore_root_company_validation = True
doc.update({"company": company, "account_currency": None,
"parent": acc_name_map[company], "parent_account": acc_name_map[company]})
doc.update({
"company": company,
"account_currency": None,
"parent_account": parent_acc_name_map[company]
})
doc.save()
frappe.msgprint(_("Account {0} is added in the child company {1}")
.format(doc.name, company))
@@ -261,7 +268,7 @@ def update_account_number(name, account_name, account_number=None):
new_name = get_account_autoname(account_number, account_name, account.company)
if name != new_name:
frappe.rename_doc("Account", name, new_name, ignore_permissions=1)
frappe.rename_doc("Account", name, new_name, force=1)
return new_name
@frappe.whitelist()
@@ -280,7 +287,7 @@ def merge_account(old, new, is_group, root_type, company):
frappe.db.set_value("Account", new, "parent_account",
frappe.db.get_value("Account", old, "parent_account"))
frappe.rename_doc("Account", old, new, merge=1, ignore_permissions=1)
frappe.rename_doc("Account", old, new, merge=1, force=1)
return new

View File

@@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.model.document import Document
class AccountingPeriod(Document):
@@ -16,7 +17,7 @@ class AccountingPeriod(Document):
def autoname(self):
company_abbr = frappe.get_cached_value('Company', self.company, "abbr")
self.name = " - ".join([self.period_name, company_abbr])
def validate_overlap(self):
existing_accounting_period = frappe.db.sql("""select name from `tabAccounting Period`
where (
@@ -33,7 +34,7 @@ class AccountingPeriod(Document):
}, as_dict=True)
if len(existing_accounting_period) > 0:
frappe.throw("Accounting Period overlaps with {0}".format(existing_accounting_period[0].get("name")))
frappe.throw(_("Accounting Period overlaps with {0}".format(existing_accounting_period[0].get("name"))))
def get_doctypes_for_closing(self):
docs_for_closing = []

View File

@@ -43,8 +43,13 @@ frappe.ui.form.on('Bank Guarantee', {
reference_docname: function(frm) {
if (frm.doc.reference_docname && frm.doc.reference_doctype) {
let fields_to_fetch = ["project", "grand_total"];
let fields_to_fetch = ["grand_total"];
let party_field = frm.doc.reference_doctype == "Sales Order" ? "customer" : "supplier";
if (frm.doc.reference_doctype == "Sales Order") {
fields_to_fetch.push("project");
}
fields_to_fetch.push(party_field);
frappe.call({
method: "erpnext.accounts.doctype.bank_guarantee.bank_guarantee.get_vouchar_detials",

View File

@@ -22,7 +22,5 @@ class BankGuarantee(Document):
@frappe.whitelist()
def get_vouchar_detials(column_list, doctype, docname):
print (column_list, doctype, docname)
return frappe.db.sql(''' select {columns} from `tab{doctype}` where name=%s'''
.format(columns=", ".join(json.loads(column_list)), doctype=doctype), docname, as_dict=1)[0]

View File

@@ -48,7 +48,7 @@ class BankStatementTransactionEntry(Document):
def get_statement_headers(self):
if not self.bank_settings:
frappe.throw("Bank Data mapper doesn't exist")
frappe.throw(_("Bank Data mapper doesn't exist"))
mapper_doc = frappe.get_doc("Bank Statement Settings", self.bank_settings)
headers = {entry.mapped_header:entry.stmt_header for entry in mapper_doc.header_items}
return headers
@@ -57,7 +57,7 @@ class BankStatementTransactionEntry(Document):
if self.bank_statement is None: return
filename = self.bank_statement.split("/")[-1]
if (len(self.new_transaction_items + self.reconciled_transaction_items) > 0):
frappe.throw("Transactions already retreived from the statement")
frappe.throw(_("Transactions already retreived from the statement"))
date_format = frappe.get_value("Bank Statement Settings", self.bank_settings, "date_format")
if (date_format is None):
@@ -314,7 +314,7 @@ class BankStatementTransactionEntry(Document):
try:
reconcile_against_document(lst)
except:
frappe.throw("Exception occurred while reconciling {0}".format(payment.reference_name))
frappe.throw(_("Exception occurred while reconciling {0}".format(payment.reference_name)))
def submit_payment_entries(self):
for payment in self.new_transaction_items:
@@ -414,7 +414,7 @@ def get_transaction_entries(filename, headers):
elif (filename.lower().endswith("xls")):
rows = get_rows_from_xls_file(filename)
else:
frappe.throw("Only .csv and .xlsx files are supported currently")
frappe.throw(_("Only .csv and .xlsx files are supported currently"))
stmt_headers = headers.values()
for row in rows:

View File

@@ -121,7 +121,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Settled",
"default": "Pending",
"fetch_if_empty": 0,
"fieldname": "status",
"fieldtype": "Select",
@@ -755,7 +755,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2019-04-26 14:32:16.437813",
"modified": "2019-05-11 05:27:55.244721",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Bank Transaction",

View File

@@ -36,6 +36,10 @@ class BankTransaction(StatusUpdater):
frappe.db.set_value(self.doctype, self.name, "allocated_amount", 0)
frappe.db.set_value(self.doctype, self.name, "unallocated_amount", abs(flt(self.credit) - flt(self.debit)))
amount = self.debit or self.credit
if amount == self.allocated_amount:
frappe.db.set_value(self.doctype, self.name, "status", "Reconciled")
self.reload()
def clear_linked_payment_entries(self):
@@ -87,7 +91,7 @@ def get_paid_amount(payment_entry):
return frappe.db.get_value(payment_entry.payment_document, payment_entry.payment_entry, "total_amount_reimbursed")
else:
frappe.throw("Please reconcile {0}: {1} manually".format(payment_entry.payment_document, payment_entry.payment_entry))
frappe.throw(_("Please reconcile {0}: {1} manually".format(payment_entry.payment_document, payment_entry.payment_entry)))
@frappe.whitelist()
def unclear_reference_payment(doctype, docname):

View File

@@ -21,9 +21,29 @@ frappe.ui.form.on('Exchange Rate Revaluation', {
refresh: function(frm) {
if(frm.doc.docstatus==1) {
frm.add_custom_button(__('Make Journal Entry'), function() {
return frm.events.make_jv(frm);
});
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(){
frappe.route_options = {
'reference_type': 'Exchange Rate Revaluation',
'reference_name': frm.doc.name
};
frappe.set_route("List", "Journal Entry");
}, __("View"));
} else {
frm.add_custom_button(__('Create Journal Entry'), function() {
return frm.events.make_jv(frm);
});
}
}, 'Journal Entry');
}
},
@@ -39,8 +59,6 @@ frappe.ui.form.on('Exchange Rate Revaluation', {
});
frm.events.get_total_gain_loss(frm);
refresh_field("accounts");
} else {
frappe.msgprint(__("No records found"));
}
}
});
@@ -54,7 +72,7 @@ frappe.ui.form.on('Exchange Rate Revaluation', {
d.gain_loss = flt(d.new_balance_in_base_currency, precision("new_balance_in_base_currency", d)) - flt(d.balance_in_base_currency, precision("balance_in_base_currency", d));
total_gain_loss += flt(d.gain_loss, precision("gain_loss", d));
});
frm.set_value("total_gain_loss", flt(total_gain_loss, precision("total_gain_loss")));
frm.refresh_fields();
},

View File

@@ -22,7 +22,7 @@ class ExchangeRateRevaluation(Document):
- flt(d.balance_in_base_currency, d.precision("balance_in_base_currency"))
total_gain_loss += flt(d.gain_loss, d.precision("gain_loss"))
self.total_gain_loss = flt(total_gain_loss, self.precision("total_gain_loss"))
def validate_mandatory(self):
if not (self.company and self.posting_date):
frappe.throw(_("Please select Company and Posting Date to getting entries"))
@@ -33,8 +33,9 @@ class ExchangeRateRevaluation(Document):
company_currency = erpnext.get_company_currency(self.company)
precision = get_field_precision(frappe.get_meta("Exchange Rate Revaluation Account")
.get_field("new_balance_in_base_currency"), company_currency)
for d in self.get_accounts_from_gle():
account_details = self.get_accounts_from_gle()
for d in account_details:
current_exchange_rate = d.balance / d.balance_in_account_currency \
if d.balance_in_account_currency else 0
new_exchange_rate = get_exchange_rate(d.account_currency, company_currency, self.posting_date)
@@ -52,6 +53,10 @@ class ExchangeRateRevaluation(Document):
"new_exchange_rate": new_exchange_rate,
"new_balance_in_base_currency": new_balance_in_base_currency
})
if not accounts:
self.throw_invalid_response_message(account_details)
return accounts
def get_accounts_from_gle(self):
@@ -83,11 +88,18 @@ class ExchangeRateRevaluation(Document):
return account_details
def throw_invalid_response_message(self, account_details):
if account_details:
message = _("No outstanding invoices require exchange rate revaluation")
else:
message = _("No outstanding invoices found")
frappe.msgprint(message)
def make_jv_entry(self):
if self.total_gain_loss == 0:
return
unrealized_exchange_gain_loss_account = frappe.get_cached_value('Company', self.company,
unrealized_exchange_gain_loss_account = frappe.get_cached_value('Company', self.company,
"unrealized_exchange_gain_loss_account")
if not unrealized_exchange_gain_loss_account:
frappe.throw(_("Please set Unrealized Exchange Gain/Loss Account in Company {0}")

View File

@@ -1,461 +1,475 @@
{
"allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2018-04-13 18:30:06.110433",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2018-04-13 18:30:06.110433",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "account",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Account",
"length": 0,
"no_copy": 0,
"options": "Account",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "account",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Account",
"length": 0,
"no_copy": 0,
"options": "Account",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "party_type",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Party Type",
"length": 0,
"no_copy": 0,
"options": "DocType",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "party_type",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Party Type",
"length": 0,
"no_copy": 0,
"options": "DocType",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "party",
"fieldtype": "Dynamic Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Party",
"length": 0,
"no_copy": 0,
"options": "party_type",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "party",
"fieldtype": "Dynamic Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Party",
"length": 0,
"no_copy": 0,
"options": "party_type",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_2",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_2",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "account_currency",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Account Currency",
"length": 0,
"no_copy": 0,
"options": "Currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "account_currency",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Account Currency",
"length": 0,
"no_copy": 0,
"options": "Currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "balance_in_account_currency",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Balance In Account Currency",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "balance_in_account_currency",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Balance In Account Currency",
"length": 0,
"no_copy": 0,
"options": "account_currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "balances",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "balances",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "current_exchange_rate",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Current Exchange Rate",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "current_exchange_rate",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Current Exchange Rate",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "balance_in_base_currency",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Balance In Base Currency",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "balance_in_base_currency",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Balance In Base Currency",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_9",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_9",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "new_exchange_rate",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "New Exchange Rate",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "new_exchange_rate",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "New Exchange Rate",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "new_balance_in_base_currency",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "New Balance In Base Currency",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "new_balance_in_base_currency",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "New Balance In Base Currency",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "gain_loss",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Gain/Loss",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "gain_loss",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Gain/Loss",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2019-01-07 16:52:07.327930",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Exchange Rate Revaluation Account",
"name_case": "",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0,
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2019-06-26 18:57:51.762345",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Exchange Rate Revaluation Account",
"name_case": "",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0,
"track_views": 0
}

View File

@@ -425,8 +425,9 @@ class JournalEntry(AccountsController):
pay_to_recd_from = frappe.db.get_value(d.party_type, d.party,
"customer_name" if d.party_type=="Customer" else "supplier_name")
party_amount += (d.debit_in_account_currency or d.credit_in_account_currency)
party_account_currency = d.account_currency
if pay_to_recd_from and pay_to_recd_from == d.party:
party_amount += (d.debit_in_account_currency or d.credit_in_account_currency)
party_account_currency = d.account_currency
elif frappe.db.get_value("Account", d.account, "account_type") in ["Bank", "Cash"]:
bank_amount += (d.debit_in_account_currency or d.credit_in_account_currency)

View File

@@ -160,7 +160,7 @@ class PaymentEntry(AccountsController):
d.reference_name, self.party_account_currency)
for field, value in iteritems(ref_details):
if not d.get(field) or force:
if field == 'exchange_rate' or not d.get(field) or force:
d.set(field, value)
def validate_payment_type(self):

View File

@@ -167,7 +167,12 @@ def get_pricing_rule_for_item(args):
if args.transaction_type=="selling":
if args.customer and not (args.customer_group and args.territory):
customer = frappe.get_cached_value("Customer", args.customer, ["customer_group", "territory"])
if args.quotation_to and args.quotation_to != 'Customer':
customer = frappe._dict()
else:
customer = frappe.get_cached_value("Customer", args.customer, ["customer_group", "territory"])
if customer:
args.customer_group, args.territory = customer
@@ -345,7 +350,7 @@ def filter_pricing_rules(args, pricing_rules):
if len(pricing_rules) > 1:
rate_or_discount = list(set([d.rate_or_discount for d in pricing_rules]))
if len(rate_or_discount) == 1 and rate_or_discount[0] == "Discount Percentage":
pricing_rules = filter(lambda x: x.for_price_list==args.price_list, pricing_rules) \
pricing_rules = list(filter(lambda x: x.for_price_list==args.price_list, pricing_rules)) \
or pricing_rules
if len(pricing_rules) > 1 and not args.for_shopping_cart:
@@ -368,7 +373,7 @@ def apply_internal_priority(pricing_rules, field_set, args):
filtered_rules = []
for field in field_set:
if args.get(field):
filtered_rules = filter(lambda x: x[field]==args[field], pricing_rules)
filtered_rules = list(filter(lambda x: x[field]==args[field], pricing_rules))
if filtered_rules: break
return filtered_rules or pricing_rules

View File

@@ -18,9 +18,6 @@ class TestPricingRule(unittest.TestCase):
frappe.db.sql("delete from `tabPricing Rule`")
def test_pricing_rule_for_discount(self):
from erpnext.stock.get_item_details import get_item_details
from frappe import MandatoryError
test_record = {
"doctype": "Pricing Rule",
"title": "_Test Pricing Rule",
@@ -94,9 +91,6 @@ class TestPricingRule(unittest.TestCase):
self.assertEquals(details.get("discount_percentage"), 15)
def test_pricing_rule_for_margin(self):
from erpnext.stock.get_item_details import get_item_details
from frappe import MandatoryError
test_record = {
"doctype": "Pricing Rule",
"title": "_Test Pricing Rule",
@@ -139,9 +133,6 @@ class TestPricingRule(unittest.TestCase):
self.assertEquals(details.get("margin_rate_or_amount"), 10)
def test_pricing_rule_for_variants(self):
from erpnext.stock.get_item_details import get_item_details
from frappe import MandatoryError
if not frappe.db.exists("Item", "Test Variant PRT"):
frappe.get_doc({
"doctype": "Item",

View File

@@ -157,7 +157,7 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
can_change_release_date: function(date) {
const diff = frappe.datetime.get_diff(date, frappe.datetime.nowdate());
if (diff < 0) {
frappe.throw('New release date should be in the future');
frappe.throw(__('New release date should be in the future'));
return false;
} else {
return true;

View File

@@ -100,6 +100,7 @@ class PurchaseInvoice(BuyingController):
self.validate_fixed_asset()
self.create_remarks()
self.set_status()
self.validate_purchase_receipt_if_update_stock()
validate_inter_company_party(self.doctype, self.supplier, self.company, self.inter_company_invoice_reference)
def validate_release_date(self):
@@ -284,7 +285,7 @@ class PurchaseInvoice(BuyingController):
def update_status_updater_args(self):
if cint(self.update_stock):
self.status_updater.extend([{
self.status_updater.append({
'source_dt': 'Purchase Invoice Item',
'target_dt': 'Purchase Order Item',
'join_field': 'po_detail',
@@ -292,28 +293,29 @@ class PurchaseInvoice(BuyingController):
'target_parent_dt': 'Purchase Order',
'target_parent_field': 'per_received',
'target_ref_field': 'qty',
'source_field': 'qty',
'source_field': 'received_qty',
'second_source_dt': 'Purchase Receipt Item',
'second_source_field': 'received_qty',
'second_join_field': 'purchase_order_item',
'percent_join_field':'purchase_order',
# 'percent_join_field': 'prevdoc_docname',
'overflow_type': 'receipt',
'extra_cond': """ and exists(select name from `tabPurchase Invoice`
where name=`tabPurchase Invoice Item`.parent and update_stock = 1)"""
},
{
'source_dt': 'Purchase Invoice Item',
'target_dt': 'Purchase Order Item',
'join_field': 'po_detail',
'target_field': 'returned_qty',
'target_parent_dt': 'Purchase Order',
# 'target_parent_field': 'per_received',
# 'target_ref_field': 'qty',
'source_field': '-1 * qty',
# 'percent_join_field': 'prevdoc_docname',
# 'overflow_type': 'receipt',
'extra_cond': """ and exists (select name from `tabPurchase Invoice`
where name=`tabPurchase Invoice Item`.parent and update_stock=1 and is_return=1)"""
}
])
})
if cint(self.is_return):
self.status_updater.append({
'source_dt': 'Purchase Invoice Item',
'target_dt': 'Purchase Order Item',
'join_field': 'po_detail',
'target_field': 'returned_qty',
'source_field': '-1 * qty',
'second_source_dt': 'Purchase Receipt Item',
'second_source_field': '-1 * qty',
'second_join_field': 'purchase_order_item',
'overflow_type': 'receipt',
'extra_cond': """ and exists (select name from `tabPurchase Invoice`
where name=`tabPurchase Invoice Item`.parent and update_stock=1 and is_return=1)"""
})
def validate_purchase_receipt_if_update_stock(self):
if self.update_stock:
@@ -327,13 +329,13 @@ class PurchaseInvoice(BuyingController):
self.check_prev_docstatus()
self.update_status_updater_args()
self.update_prevdoc_status()
frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
self.company, self.base_grand_total)
if not self.is_return:
self.update_against_document_in_jv()
self.update_prevdoc_status()
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
self.update_billing_status_in_pr()
@@ -482,9 +484,13 @@ class PurchaseInvoice(BuyingController):
"credit": flt(item.rm_supp_cost)
}, warehouse_account[self.supplier_warehouse]["account_currency"]))
elif not item.is_fixed_asset or (item.is_fixed_asset and is_cwip_accounting_disabled()):
expense_account = (item.expense_account
if (not item.enable_deferred_expense or self.is_return) else item.deferred_expense_account)
gl_entries.append(
self.get_gl_dict({
"account": item.expense_account if not item.enable_deferred_expense else item.deferred_expense_account,
"account": expense_account,
"against": self.supplier,
"debit": flt(item.base_net_amount, item.precision("base_net_amount")),
"debit_in_account_currency": (flt(item.base_net_amount,
@@ -763,13 +769,13 @@ class PurchaseInvoice(BuyingController):
self.check_for_closed_status()
self.update_status_updater_args()
self.update_prevdoc_status()
if not self.is_return:
from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
if frappe.db.get_single_value('Accounts Settings', 'unlink_payment_on_cancellation_of_invoice'):
unlink_ref_doc_from_payment_entries(self)
self.update_prevdoc_status()
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
self.update_billing_status_in_pr()

View File

@@ -6,8 +6,8 @@ frappe.listview_settings['Purchase Invoice'] = {
add_fields: ["supplier", "supplier_name", "base_grand_total", "outstanding_amount", "due_date", "company",
"currency", "is_return", "release_date", "on_hold"],
get_indicator: function(doc) {
if(cint(doc.is_return)==1) {
return [__("Return"), "darkgrey", "is_return,=,Yes"];
if(flt(doc.outstanding_amount) < 0 && doc.docstatus == 1) {
return [__("Debit Note Issued"), "darkgrey", "outstanding_amount,<,0"]
} else if(flt(doc.outstanding_amount) > 0 && doc.docstatus==1) {
if(cint(doc.on_hold) && !doc.release_date) {
return [__("On Hold"), "darkgrey"];
@@ -18,9 +18,9 @@ frappe.listview_settings['Purchase Invoice'] = {
} else {
return [__("Unpaid"), "orange", "outstanding_amount,>,0|due,>=,Today"];
}
} else if(flt(doc.outstanding_amount) < 0 && doc.docstatus == 1) {
return [__("Debit Note Issued"), "darkgrey", "outstanding_amount,<,0"]
}else if(flt(doc.outstanding_amount)==0 && doc.docstatus==1) {
} else if(cint(doc.is_return)) {
return [__("Return"), "darkgrey", "is_return,=,Yes"];
} else if(flt(doc.outstanding_amount)==0 && doc.docstatus==1) {
return [__("Paid"), "green", "outstanding_amount,=,0"];
}
}

View File

@@ -402,9 +402,9 @@ class TestPurchaseInvoice(unittest.TestCase):
pi.save()
pi.submit()
self.assertEqual(pi.payment_schedule[0].payment_amount, 756.15)
self.assertEqual(pi.payment_schedule[0].payment_amount, 606.15)
self.assertEqual(pi.payment_schedule[0].due_date, pi.posting_date)
self.assertEqual(pi.payment_schedule[1].payment_amount, 756.15)
self.assertEqual(pi.payment_schedule[1].payment_amount, 606.15)
self.assertEqual(pi.payment_schedule[1].due_date, add_days(pi.posting_date, 30))
pi.load_from_db()

View File

@@ -0,0 +1,38 @@
frappe.ui.form.on("Sales Invoice", {
setup: function(frm) {
frm.set_query('transporter', function() {
return {
filters: {
'is_transporter': 1
}
};
});
frm.set_query('driver', function(doc) {
return {
filters: {
'transporter': doc.transporter
}
};
});
},
refresh: function(frm) {
if(frm.doc.docstatus == 1 && !frm.is_dirty()
&& !frm.doc.is_return && !frm.doc.ewaybill) {
frm.add_custom_button('e-Way Bill JSON', () => {
var w = window.open(
frappe.urllib.get_full_url(
"/api/method/erpnext.regional.india.utils.generate_ewb_json?"
+ "dt=" + encodeURIComponent(frm.doc.doctype)
+ "&dn=" + encodeURIComponent(frm.doc.name)
)
);
if (!w) {
frappe.msgprint(__("Please enable pop-ups")); return;
}
}, __("Make"));
}
}
});

View File

@@ -0,0 +1,33 @@
var globalOnload = frappe.listview_settings['Sales Invoice'].onload;
frappe.listview_settings['Sales Invoice'].onload = function (doclist) {
// Provision in case onload event is added to sales_invoice.js in future
if (globalOnload) {
globalOnload(doclist);
}
const action = () => {
const selected_docs = doclist.get_checked_items();
const docnames = doclist.get_checked_items(true);
for (let doc of selected_docs) {
if (doc.docstatus !== 1) {
frappe.throw(__("e-Way Bill JSON can only be generated from a submitted document"));
}
}
var w = window.open(
frappe.urllib.get_full_url(
"/api/method/erpnext.regional.india.utils.generate_ewb_json?"
+ "dt=" + encodeURIComponent(doclist.doctype)
+ "&dn=" + encodeURIComponent(docnames)
)
);
if (!w) {
frappe.msgprint(__("Please enable pop-ups")); return;
}
};
doclist.page.add_actions_menu_item(__('Generate e-Way Bill JSON'), action, false);
};

View File

@@ -174,9 +174,13 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
method: "erpnext.selling.doctype.quotation.quotation.make_sales_invoice",
source_doctype: "Quotation",
target: me.frm,
setters: {
customer: me.frm.doc.customer || undefined,
},
setters: [{
fieldtype: 'Link',
label: __('Customer'),
options: 'Customer',
fieldname: 'party_name',
default: me.frm.doc.customer,
}],
get_query_filters: {
docstatus: 1,
status: ["!=", "Lost"],
@@ -371,6 +375,10 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
me.frm.pos_print_format = r.message.print_format;
}
me.frm.script_manager.trigger("update_stock");
if(me.frm.doc.taxes_and_charges) {
me.frm.script_manager.trigger("taxes_and_charges");
}
frappe.model.set_default_values(me.frm.doc);
me.set_dynamic_labels();
me.calculate_taxes_and_totals();

View File

@@ -54,8 +54,8 @@ class SalesInvoice(SellingController):
def set_indicator(self):
"""Set indicator for portal"""
if cint(self.is_return) == 1:
self.indicator_title = _("Return")
if self.outstanding_amount < 0:
self.indicator_title = _("Credit Note Issued")
self.indicator_color = "darkgrey"
elif self.outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()):
self.indicator_color = "orange"
@@ -63,8 +63,8 @@ class SalesInvoice(SellingController):
elif self.outstanding_amount > 0 and getdate(self.due_date) < getdate(nowdate()):
self.indicator_color = "red"
self.indicator_title = _("Overdue")
elif self.outstanding_amount < 0:
self.indicator_title = _("Credit Note Issued")
elif cint(self.is_return) == 1:
self.indicator_title = _("Return")
self.indicator_color = "darkgrey"
else:
self.indicator_color = "green"
@@ -256,7 +256,7 @@ class SalesInvoice(SellingController):
def update_status_updater_args(self):
if cint(self.update_stock):
self.status_updater.extend([{
self.status_updater.append({
'source_dt':'Sales Invoice Item',
'target_dt':'Sales Order Item',
'target_parent_dt':'Sales Order',
@@ -274,21 +274,20 @@ class SalesInvoice(SellingController):
'overflow_type': 'delivery',
'extra_cond': """ and exists(select name from `tabSales Invoice`
where name=`tabSales Invoice Item`.parent and update_stock = 1)"""
},
{
'source_dt': 'Sales Invoice Item',
'target_dt': 'Sales Order Item',
'join_field': 'so_detail',
'target_field': 'returned_qty',
'target_parent_dt': 'Sales Order',
# 'target_parent_field': 'per_delivered',
# 'target_ref_field': 'qty',
'source_field': '-1 * qty',
# 'percent_join_field': 'sales_order',
# 'overflow_type': 'delivery',
'extra_cond': """ and exists (select name from `tabSales Invoice` where name=`tabSales Invoice Item`.parent and update_stock=1 and is_return=1)"""
}
])
})
if cint(self.is_return):
self.status_updater.append({
'source_dt': 'Sales Invoice Item',
'target_dt': 'Sales Order Item',
'join_field': 'so_detail',
'target_field': 'returned_qty',
'target_parent_dt': 'Sales Order',
'source_field': '-1 * qty',
'second_source_dt': 'Delivery Note Item',
'second_source_field': '-1 * qty',
'second_join_field': 'so_detail',
'extra_cond': """ and exists (select name from `tabSales Invoice` where name=`tabSales Invoice Item`.parent and update_stock=1 and is_return=1)"""
})
def check_credit_limit(self):
from erpnext.selling.doctype.customer.customer import check_credit_limit
@@ -488,7 +487,7 @@ class SalesInvoice(SellingController):
"""Set against account for debit to account"""
against_acc = []
for d in self.get('items'):
if d.income_account not in against_acc:
if d.income_account and d.income_account not in against_acc:
against_acc.append(d.income_account)
self.against_income_account = ','.join(against_acc)
@@ -504,12 +503,15 @@ class SalesInvoice(SellingController):
def so_dn_required(self):
"""check in manage account if sales order / delivery note required or not."""
if self.is_return:
return
dic = {'Sales Order':['so_required', 'is_pos'],'Delivery Note':['dn_required', 'update_stock']}
for i in dic:
if frappe.db.get_single_value('Selling Settings', dic[i][0]) == 'Yes':
for d in self.get('items'):
if frappe.get_cached_value('Item', d.item_code, 'is_stock_item') == 1 \
and not d.get(i.lower().replace(' ','_')) and not self.get(dic[i][1]):
is_stock_item = frappe.get_cached_value('Item', d.item_code, 'is_stock_item')
if (d.item_code and is_stock_item == 1\
and not d.get(i.lower().replace(' ','_')) and not self.get(dic[i][1])):
msgprint(_("{0} is mandatory for Item {1}").format(i,d.item_code), raise_exception=1)
@@ -768,7 +770,14 @@ class SalesInvoice(SellingController):
if item.is_fixed_asset:
asset = frappe.get_doc("Asset", item.asset)
fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset, item.base_net_amount)
if (len(asset.finance_books) > 1 and not item.finance_book
and asset.finance_books[0].finance_book):
frappe.throw(_("Select finance book for the item {0} at row {1}")
.format(item.item_code, item.idx))
fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset,
item.base_net_amount, item.finance_book)
for gle in fixed_asset_gl_entries:
gle["against"] = self.customer
gl_entries.append(self.get_gl_dict(gle))
@@ -776,10 +785,13 @@ class SalesInvoice(SellingController):
asset.db_set("disposal_date", self.posting_date)
asset.set_status("Sold" if self.docstatus==1 else None)
else:
account_currency = get_account_currency(item.income_account)
income_account = (item.income_account
if (not item.enable_deferred_revenue or self.is_return) else item.deferred_revenue_account)
account_currency = get_account_currency(income_account)
gl_entries.append(
self.get_gl_dict({
"account": item.income_account if not item.enable_deferred_revenue else item.deferred_revenue_account,
"account": income_account,
"against": self.customer,
"credit": flt(item.base_net_amount, item.precision("base_net_amount")),
"credit_in_account_currency": (flt(item.base_net_amount, item.precision("base_net_amount"))
@@ -1167,6 +1179,8 @@ class SalesInvoice(SellingController):
self.set_missing_values(for_validate = True)
def validate_inter_company_party(doctype, party, company, inter_company_invoice_reference):
if not party:
return
if doctype == "Sales Invoice":
partytype, ref_partytype, internal = "Customer", "Supplier", "is_internal_customer"
ref_doc = "Purchase Invoice"

View File

@@ -6,16 +6,16 @@ frappe.listview_settings['Sales Invoice'] = {
add_fields: ["customer", "customer_name", "base_grand_total", "outstanding_amount", "due_date", "company",
"currency", "is_return"],
get_indicator: function(doc) {
if(cint(doc.is_return)==1) {
return [__("Return"), "darkgrey", "is_return,=,Yes"];
} else if(flt(doc.outstanding_amount)==0) {
return [__("Paid"), "green", "outstanding_amount,=,0"]
} else if(flt(doc.outstanding_amount) < 0) {
if(flt(doc.outstanding_amount) < 0) {
return [__("Credit Note Issued"), "darkgrey", "outstanding_amount,<,0"]
}else if (flt(doc.outstanding_amount) > 0 && doc.due_date >= frappe.datetime.get_today()) {
} else if (flt(doc.outstanding_amount) > 0 && doc.due_date >= frappe.datetime.get_today()) {
return [__("Unpaid"), "orange", "outstanding_amount,>,0|due_date,>,Today"]
} else if (flt(doc.outstanding_amount) > 0 && doc.due_date < frappe.datetime.get_today()) {
return [__("Overdue"), "red", "outstanding_amount,>,0|due_date,<=,Today"]
} else if(cint(doc.is_return)) {
return [__("Return"), "darkgrey", "is_return,=,Yes"];
} else if(flt(doc.outstanding_amount)==0) {
return [__("Paid"), "green", "outstanding_amount,=,0"]
}
},
right_column: "grand_total"

View File

@@ -18,6 +18,8 @@ from erpnext.accounts.doctype.account.test_account import get_inventory_account,
from erpnext.controllers.taxes_and_totals import get_itemised_tax_breakup_data
from erpnext.stock.doctype.item.test_item import create_item
from six import iteritems
from erpnext.regional.india.utils import get_ewb_data
class TestSalesInvoice(unittest.TestCase):
def make(self):
w = frappe.copy_doc(test_records[0])
@@ -1611,6 +1613,110 @@ class TestSalesInvoice(unittest.TestCase):
self.assertEqual(expected_gle[i][2], gle.credit)
self.assertEqual(getdate(expected_gle[i][3]), gle.posting_date)
def test_eway_bill_json(self):
if not frappe.db.exists('Address', '_Test Address for Eway bill-Billing'):
address = frappe.get_doc({
"address_line1": "_Test Address Line 1",
"address_title": "_Test Address for Eway bill",
"address_type": "Billing",
"city": "_Test City",
"state": "Test State",
"country": "India",
"doctype": "Address",
"is_primary_address": 1,
"phone": "+91 0000000000",
"gstin": "27AAECE4835E1ZR",
"gst_state": "Maharashtra",
"gst_state_number": "27",
"pincode": "401108"
}).insert()
address.append("links", {
"link_doctype": "Company",
"link_name": "_Test Company"
})
address.save()
if not frappe.db.exists('Address', '_Test Customer-Address for Eway bill-Shipping'):
address = frappe.get_doc({
"address_line1": "_Test Address Line 1",
"address_title": "_Test Customer-Address for Eway bill",
"address_type": "Shipping",
"city": "_Test City",
"state": "Test State",
"country": "India",
"doctype": "Address",
"is_primary_address": 1,
"phone": "+91 0000000000",
"gst_state": "Maharashtra",
"gst_state_number": "27",
"pincode": "410038"
}).insert()
address.append("links", {
"link_doctype": "Customer",
"link_name": "_Test Customer"
})
address.save()
gst_settings = frappe.get_doc("GST Settings")
gst_account = frappe.get_all(
"GST Account",
fields=["cgst_account", "sgst_account", "igst_account"],
filters = {"company": "_Test Company"})
if not gst_account:
gst_settings.append("gst_accounts", {
"company": "_Test Company",
"cgst_account": "CGST - _TC",
"sgst_account": "SGST - _TC",
"igst_account": "IGST - _TC",
})
gst_settings.save()
si = create_sales_invoice(do_not_save =1, rate = '60000')
si.distance = 2000
si.company_address = "_Test Address for Eway bill-Billing"
si.customer_address = "_Test Customer-Address for Eway bill-Shipping"
si.vehicle_no = "KA12KA1234"
si.append("taxes", {
"charge_type": "On Net Total",
"account_head": "CGST - _TC",
"cost_center": "Main - _TC",
"description": "CGST @ 9.0",
"rate": 9
})
si.append("taxes", {
"charge_type": "On Net Total",
"account_head": "SGST - _TC",
"cost_center": "Main - _TC",
"description": "SGST @ 9.0",
"rate": 9
})
si.submit()
data = get_ewb_data("Sales Invoice", si.name)
self.assertEqual(data['version'], '1.0.1118')
self.assertEqual(data['billLists'][0]['fromGstin'], '27AAECE4835E1ZR')
self.assertEqual(data['billLists'][0]['fromTrdName'], '_Test Company')
self.assertEqual(data['billLists'][0]['toTrdName'], '_Test Customer')
self.assertEqual(data['billLists'][0]['vehicleType'], 'R')
self.assertEqual(data['billLists'][0]['totalValue'], 60000)
self.assertEqual(data['billLists'][0]['cgstValue'], 5400)
self.assertEqual(data['billLists'][0]['sgstValue'], 5400)
self.assertEqual(data['billLists'][0]['vehicleNo'], 'KA12KA1234')
self.assertEqual(data['billLists'][0]['itemList'][0]['taxableAmount'], 60000)
def create_sales_invoice(**args):
si = frappe.new_doc("Sales Invoice")
args = frappe._dict(args)

View File

@@ -21,6 +21,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "barcode",
"fieldtype": "Data",
"hidden": 0,
@@ -52,6 +53,7 @@
"bold": 1,
"collapsible": 0,
"columns": 4,
"fetch_if_empty": 0,
"fieldname": "item_code",
"fieldtype": "Link",
"hidden": 0,
@@ -86,6 +88,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "col_break1",
"fieldtype": "Column Break",
"hidden": 0,
@@ -116,6 +119,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "item_name",
"fieldtype": "Data",
"hidden": 0,
@@ -149,6 +153,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "customer_item_code",
"fieldtype": "Data",
"hidden": 1,
@@ -180,6 +185,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "section_break_6",
"fieldtype": "Section Break",
"hidden": 0,
@@ -212,6 +218,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "description",
"fieldtype": "Text Editor",
"hidden": 0,
@@ -247,6 +254,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_8",
"fieldtype": "Column Break",
"hidden": 0,
@@ -278,6 +286,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "image_view",
"fieldtype": "Image",
"hidden": 0,
@@ -311,6 +320,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "image",
"fieldtype": "Attach",
"hidden": 1,
@@ -343,6 +353,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "quantity_and_rate",
"fieldtype": "Section Break",
"hidden": 0,
@@ -374,6 +385,7 @@
"bold": 1,
"collapsible": 0,
"columns": 2,
"fetch_if_empty": 0,
"fieldname": "qty",
"fieldtype": "Float",
"hidden": 0,
@@ -407,6 +419,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "stock_uom",
"fieldtype": "Link",
"hidden": 0,
@@ -439,6 +452,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "col_break2",
"fieldtype": "Column Break",
"hidden": 0,
@@ -469,6 +483,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "uom",
"fieldtype": "Link",
"hidden": 0,
@@ -502,6 +517,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "conversion_factor",
"fieldtype": "Float",
"hidden": 0,
@@ -534,6 +550,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "stock_qty",
"fieldtype": "Float",
"hidden": 0,
@@ -566,6 +583,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "section_break_17",
"fieldtype": "Section Break",
"hidden": 0,
@@ -597,6 +615,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "price_list_rate",
"fieldtype": "Currency",
"hidden": 0,
@@ -631,6 +650,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "base_price_list_rate",
"fieldtype": "Currency",
"hidden": 0,
@@ -665,6 +685,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "discount_and_margin",
"fieldtype": "Section Break",
"hidden": 0,
@@ -698,6 +719,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "price_list_rate",
"fetch_if_empty": 0,
"fieldname": "margin_type",
"fieldtype": "Select",
"hidden": 0,
@@ -732,6 +754,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.margin_type && doc.price_list_rate",
"fetch_if_empty": 0,
"fieldname": "margin_rate_or_amount",
"fieldtype": "Float",
"hidden": 0,
@@ -765,6 +788,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.margin_type && doc.price_list_rate && doc.margin_rate_or_amount",
"fetch_if_empty": 0,
"fieldname": "rate_with_margin",
"fieldtype": "Currency",
"hidden": 0,
@@ -798,6 +822,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_19",
"fieldtype": "Column Break",
"hidden": 0,
@@ -830,6 +855,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "price_list_rate",
"fetch_if_empty": 0,
"fieldname": "discount_percentage",
"fieldtype": "Percent",
"hidden": 0,
@@ -865,6 +891,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "discount_percentage",
"fetch_if_empty": 0,
"fieldname": "discount_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -899,6 +926,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.margin_type && doc.price_list_rate && doc.margin_rate_or_amount",
"fetch_if_empty": 0,
"fieldname": "base_rate_with_margin",
"fieldtype": "Currency",
"hidden": 0,
@@ -932,6 +960,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "section_break1",
"fieldtype": "Section Break",
"hidden": 0,
@@ -962,6 +991,7 @@
"bold": 1,
"collapsible": 0,
"columns": 2,
"fetch_if_empty": 0,
"fieldname": "rate",
"fieldtype": "Currency",
"hidden": 0,
@@ -996,6 +1026,7 @@
"bold": 0,
"collapsible": 0,
"columns": 2,
"fetch_if_empty": 0,
"fieldname": "amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -1030,6 +1061,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "col_break3",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1060,6 +1092,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "base_rate",
"fieldtype": "Currency",
"hidden": 0,
@@ -1094,6 +1127,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "base_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -1128,6 +1162,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "pricing_rule",
"fieldtype": "Link",
"hidden": 0,
@@ -1160,6 +1195,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "section_break_21",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1191,6 +1227,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "net_rate",
"fieldtype": "Currency",
"hidden": 0,
@@ -1224,6 +1261,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "net_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -1257,6 +1295,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_24",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1288,6 +1327,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "base_net_rate",
"fieldtype": "Currency",
"hidden": 0,
@@ -1321,6 +1361,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "base_net_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -1355,6 +1396,7 @@
"collapsible": 1,
"collapsible_depends_on": "eval:doc.delivered_by_supplier==1",
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "drop_ship",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1387,6 +1429,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "delivered_by_supplier",
"fieldtype": "Check",
"hidden": 0,
@@ -1419,6 +1462,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "accounting",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1450,6 +1494,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "income_account",
"fieldtype": "Link",
"hidden": 0,
@@ -1486,6 +1531,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "expense_account",
"fieldtype": "Link",
"hidden": 0,
@@ -1519,6 +1565,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "col_break4",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1550,6 +1597,7 @@
"collapsible": 0,
"columns": 0,
"default": ":Company",
"fetch_if_empty": 0,
"fieldname": "cost_center",
"fieldtype": "Link",
"hidden": 0,
@@ -1586,6 +1634,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "deferred_revenue",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1619,6 +1668,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "enable_deferred_revenue",
"fetch_if_empty": 0,
"fieldname": "deferred_revenue_account",
"fieldtype": "Link",
"hidden": 0,
@@ -1653,6 +1703,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "enable_deferred_revenue",
"fetch_if_empty": 0,
"fieldname": "service_stop_date",
"fieldtype": "Date",
"hidden": 0,
@@ -1686,6 +1737,7 @@
"collapsible": 0,
"columns": 0,
"default": "0",
"fetch_if_empty": 0,
"fieldname": "enable_deferred_revenue",
"fieldtype": "Check",
"hidden": 0,
@@ -1718,6 +1770,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_50",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1750,6 +1803,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "enable_deferred_revenue",
"fetch_if_empty": 0,
"fieldname": "service_start_date",
"fieldtype": "Date",
"hidden": 0,
@@ -1783,6 +1837,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "enable_deferred_revenue",
"fetch_if_empty": 0,
"fieldname": "service_end_date",
"fieldtype": "Date",
"hidden": 0,
@@ -1815,6 +1870,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "section_break_18",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1847,6 +1903,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "weight_per_unit",
"fieldtype": "Float",
"hidden": 0,
@@ -1880,6 +1937,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "total_weight",
"fieldtype": "Float",
"hidden": 0,
@@ -1912,6 +1970,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_21",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1943,6 +2002,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "weight_uom",
"fieldtype": "Link",
"hidden": 0,
@@ -1978,6 +2038,7 @@
"collapsible_depends_on": "eval:doc.serial_no || doc.batch_no",
"columns": 0,
"depends_on": "",
"fetch_if_empty": 0,
"fieldname": "warehouse_and_reference",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2009,6 +2070,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "warehouse",
"fieldtype": "Link",
"hidden": 0,
@@ -2043,6 +2105,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "target_warehouse",
"fieldtype": "Link",
"hidden": 1,
@@ -2077,6 +2140,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:!doc.__islocal",
"fetch_if_empty": 0,
"fieldname": "quality_inspection",
"fieldtype": "Link",
"hidden": 0,
@@ -2110,6 +2174,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "batch_no",
"fieldtype": "Link",
"hidden": 0,
@@ -2142,6 +2207,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "col_break5",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2172,6 +2238,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "allow_zero_valuation_rate",
"fieldtype": "Check",
"hidden": 0,
@@ -2204,6 +2271,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "serial_no",
"fieldtype": "Small Text",
"hidden": 0,
@@ -2238,6 +2306,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
"fetch_if_empty": 0,
"fieldname": "item_group",
"fieldtype": "Link",
"hidden": 1,
@@ -2272,6 +2341,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "brand",
"fieldtype": "Data",
"hidden": 1,
@@ -2305,6 +2375,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "item_tax_rate",
"fieldtype": "Small Text",
"hidden": 1,
@@ -2338,6 +2409,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "actual_batch_qty",
"fieldtype": "Float",
"hidden": 0,
@@ -2372,6 +2444,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "actual_qty",
"fieldtype": "Float",
"hidden": 0,
@@ -2405,6 +2478,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "edit_references",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2437,6 +2511,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "sales_order",
"fieldtype": "Link",
"hidden": 0,
@@ -2471,6 +2546,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "so_detail",
"fieldtype": "Data",
"hidden": 1,
@@ -2504,6 +2580,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_74",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2535,6 +2612,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "delivery_note",
"fieldtype": "Link",
"hidden": 0,
@@ -2569,6 +2647,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "dn_detail",
"fieldtype": "Data",
"hidden": 1,
@@ -2602,6 +2681,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "delivered_qty",
"fieldtype": "Float",
"hidden": 0,
@@ -2635,6 +2715,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "is_fixed_asset",
"fieldtype": "Check",
"hidden": 1,
@@ -2667,6 +2748,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "asset",
"fieldtype": "Link",
"hidden": 0,
@@ -2700,6 +2782,42 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "asset",
"fetch_if_empty": 0,
"fieldname": "finance_book",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Finance Book",
"length": 0,
"no_copy": 0,
"options": "Finance Book",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "section_break_54",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2731,6 +2849,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "page_break",
"fieldtype": "Check",
"hidden": 0,
@@ -2766,7 +2885,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2019-02-18 18:59:52.223628",
"modified": "2019-06-28 17:04:25.870346",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Item",

View File

@@ -314,13 +314,11 @@ class Subscription(Document):
self.save()
@property
def is_postpaid_to_invoice(self):
return getdate(nowdate()) > getdate(self.current_invoice_end) or \
(getdate(nowdate()) >= getdate(self.current_invoice_end) and getdate(self.current_invoice_end) == getdate(self.current_invoice_start)) and \
not self.has_outstanding_invoice()
@property
def is_prepaid_to_invoice(self):
if not self.generate_invoice_at_period_start:
return False
@@ -340,7 +338,7 @@ class Subscription(Document):
2. Change the `Subscription` status to 'Past Due Date'
3. Change the `Subscription` status to 'Cancelled'
"""
if self.is_postpaid_to_invoice or self.is_prepaid_to_invoice:
if self.is_postpaid_to_invoice() or self.is_prepaid_to_invoice():
self.generate_invoice()
if self.current_invoice_is_past_due():
self.status = 'Past Due Date'

View File

@@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.model.document import Document
from erpnext.utilities.product import get_price
@@ -13,7 +14,7 @@ class SubscriptionPlan(Document):
def validate_interval_count(self):
if self.billing_interval_count < 1:
frappe.throw('Billing Interval Count cannot be less than 1')
frappe.throw(_('Billing Interval Count cannot be less than 1'))
@frappe.whitelist()
def get_plan_rate(plan, quantity=1, customer=None):
@@ -26,7 +27,7 @@ def get_plan_rate(plan, quantity=1, customer=None):
customer_group = frappe.db.get_value("Customer", customer, "customer_group")
else:
customer_group = None
price = get_price(item_code=plan.item, price_list=plan.price_list, customer_group=customer_group, company=None, qty=quantity)
if not price:
return 0

View File

@@ -22,7 +22,7 @@ class TestTaxWithholdingCategory(unittest.TestCase):
invoices = []
# create invoices for lower than single threshold tax rate
for _ in xrange(2):
for _ in range(2):
pi = create_purchase_invoice(supplier = "Test TDS Supplier")
pi.submit()
invoices.append(pi)

View File

@@ -39,7 +39,9 @@ def add_payment_to_transaction(transaction, payment_entry, gl_entry):
"payment_entry": payment_entry.name,
"allocated_amount": allocated_amount
})
transaction.save()
transaction.update_allocations()
@frappe.whitelist()
def get_linked_payments(bank_transaction):
@@ -56,7 +58,11 @@ def get_linked_payments(bank_transaction):
return check_amount_vs_description(amount_matching, description_matching)
elif description_matching:
return sorted(description_matching, key = lambda x: x["posting_date"], reverse=True)
description_matching = filter(lambda x: not x.get('clearance_date'), description_matching)
if not description_matching:
return []
return sorted(list(description_matching), key = lambda x: x["posting_date"], reverse=True)
else:
return []
@@ -71,7 +77,7 @@ def check_matching_amount(bank_account, company, transaction):
payment_entries = frappe.get_all("Payment Entry", fields=["'Payment Entry' as doctype", "name", "paid_amount", "payment_type", "reference_no", "reference_date",
"party", "party_type", "posting_date", "{0}".format(currency_field)], filters=[["paid_amount", "like", "{0}%".format(amount)],
["docstatus", "=", "1"], ["payment_type", "=", payment_type], ["ifnull(clearance_date, '')", "=", ""], ["{0}".format(account_from_to), "=", "{0}".format(bank_account)]])
["docstatus", "=", "1"], ["payment_type", "=", [payment_type, "Internal Transfer"]], ["ifnull(clearance_date, '')", "=", ""], ["{0}".format(account_from_to), "=", "{0}".format(bank_account)]])
if transaction.credit > 0:
journal_entries = frappe.db.sql("""
@@ -97,7 +103,8 @@ def check_matching_amount(bank_account, company, transaction):
journal_entries = frappe.db.sql("""
SELECT
'Journal Entry' as doctype, je.name, je.posting_date, je.cheque_no as reference_no,
je.pay_to_recd_from as party, je.cheque_date as reference_date, jea.credit_in_account_currency as paid_amount
jea.account_currency as currency, je.pay_to_recd_from as party, je.cheque_date as reference_date,
jea.credit_in_account_currency as paid_amount
FROM
`tabJournal Entry Account` as jea
JOIN
@@ -107,12 +114,17 @@ def check_matching_amount(bank_account, company, transaction):
WHERE
(je.clearance_date is null or je.clearance_date='0000-00-00')
AND
jea.account = %s
jea.account = %(bank_account)s
AND
jea.credit_in_account_currency like %s
jea.credit_in_account_currency like %(txt)s
AND
je.docstatus = 1
""", (bank_account, amount), as_dict=True)
""", {
'bank_account': bank_account,
'txt': '%%%s%%' % amount
}, as_dict=True)
frappe.errprint(journal_entries)
if transaction.credit > 0:
sales_invoices = frappe.db.sql("""
@@ -213,9 +225,14 @@ def get_matching_descriptions_data(company, transaction):
company_currency = get_company_currency(company)
for key, value in iteritems(links):
if key == "Payment Entry":
data.extend(frappe.get_all("Payment Entry", filters=[["name", "in", value]], fields=["'Payment Entry' as doctype", "posting_date", "party", "reference_no", "reference_date", "paid_amount", "paid_to_account_currency as currency"]))
data.extend(frappe.get_all("Payment Entry", filters=[["name", "in", value]],
fields=["'Payment Entry' as doctype", "posting_date", "party", "reference_no",
"reference_date", "paid_amount", "paid_to_account_currency as currency", "clearance_date"]))
if key == "Journal Entry":
journal_entries = frappe.get_all("Journal Entry", filters=[["name", "in", value]], fields=["name", "'Journal Entry' as doctype", "posting_date", "pay_to_recd_from as party", "cheque_no as reference_no", "cheque_date as reference_date", "total_credit as paid_amount"])
journal_entries = frappe.get_all("Journal Entry", filters=[["name", "in", value]],
fields=["name", "'Journal Entry' as doctype", "posting_date",
"pay_to_recd_from as party", "cheque_no as reference_no", "cheque_date as reference_date",
"total_credit as paid_amount", "clearance_date"])
for journal_entry in journal_entries:
journal_entry_accounts = frappe.get_all("Journal Entry Account", filters={"parenttype": journal_entry["doctype"], "parent": journal_entry["name"]}, fields=["account_currency"])
journal_entry["currency"] = journal_entry_accounts[0]["account_currency"] if journal_entry_accounts else company_currency
@@ -236,6 +253,9 @@ def check_amount_vs_description(amount_matching, description_matching):
if description_matching:
for am_match in amount_matching:
for des_match in description_matching:
if des_match.get("clearance_date"):
continue
if am_match["party"] == des_match["party"]:
if am_match not in result:
result.append(am_match)

View File

@@ -1957,6 +1957,12 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
}],
function(values){
me.item_batch_no[me.items[0].item_code] = values.batch;
const item = me.frm.doc.items.find(
({ item_code }) => item_code === me.items[0].item_code
);
if (item) {
item.batch_no = values.batch;
}
},
__('Select Batch No'))
}

View File

@@ -44,7 +44,7 @@ def _get_party_details(party=None, account=None, party_type="Customer", company=
frappe.throw(_("Not permitted for {0}").format(party), frappe.PermissionError)
party = frappe.get_doc(party_type, party)
currency = party.default_currency if party.default_currency else get_company_currency(company)
currency = party.default_currency if party.get("default_currency") else get_company_currency(company)
out["taxes_and_charges"] = set_taxes(party.name, party_type, posting_date, company, out.customer_group, out.supplier_group)
out["payment_terms_template"] = get_pyt_term_template(party.name, party_type, company)
@@ -140,7 +140,7 @@ def set_other_values(out, party, party_type):
def get_default_price_list(party):
"""Return default price list for party (Document object)"""
if party.default_price_list:
if party.get("default_price_list"):
return party.default_price_list
if party.doctype == "Customer":

View File

@@ -44,6 +44,13 @@ frappe.query_reports["Accounts Payable"] = {
"default": "90",
"reqd": 1
},
{
"fieldname":"range4",
"label": __("Ageing Range 4"),
"fieldtype": "Int",
"default": "120",
"reqd": 1
},
{
"fieldname":"finance_book",
"label": __("Finance Book"),

View File

@@ -44,6 +44,13 @@ frappe.query_reports["Accounts Payable Summary"] = {
"default": "90",
"reqd": 1
},
{
"fieldname":"range4",
"label": __("Ageing Range 4"),
"fieldtype": "Int",
"default": "120",
"reqd": 1
},
{
"fieldname":"finance_book",
"label": __("Finance Book"),

View File

@@ -46,6 +46,8 @@
var range2 = report.columns[12].label;
var range3 = report.columns[13].label;
var range4 = report.columns[14].label;
var range5 = report.columns[15].label;
var range6 = report.columns[16].label;
%}
{% if(balance_row) { %}
<table class="table table-bordered table-condensed">
@@ -56,8 +58,10 @@
<col style="width: 18mm;">
<col style="width: 18mm;">
<col style="width: 18mm;">
<col style="width: 18mm;">
<col style="width: 18mm;">
<col style="width: 18mm;">
<col style="width: 18mm;">
<col style="width: 18mm;">
<col style="width: 18mm;">
</colgroup>
<thead>
@@ -67,16 +71,20 @@
<th>{%= __(range2) %}</th>
<th>{%= __(range3) %}</th>
<th>{%= __(range4) %}</th>
<th>{%= __(range5) %}</th>
<th>{%= __(range6) %}</th>
<th>{%= __("Total") %}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{%= __("Total Outstanding") %}</td>
<td class="text-right">{%= format_currency(balance_row[range1]) %}</td>
<td class="text-right">{%= format_number(balance_row[range1], null, 2) %}</td>
<td class="text-right">{%= format_currency(balance_row[range2]) %}</td>
<td class="text-right">{%= format_currency(balance_row[range3]) %}</td>
<td class="text-right">{%= format_currency(balance_row[range4]) %}</td>
<td class="text-right">{%= format_currency(balance_row[range5]) %}</td>
<td class="text-right">{%= format_currency(balance_row[range6]) %}</td>
<td class="text-right">
{%= format_currency(flt(balance_row[("outstanding_amount")]), data[data.length-1]["currency"]) %}
</td>
@@ -86,6 +94,8 @@
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td class="text-right">
{%= format_currency(flt(balance_row[("pdc/lc_amount")]), data[data.length-1]["currency"]) %}
</td>
@@ -95,6 +105,8 @@
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th class="text-right">
{%= format_currency(flt(balance_row[("outstanding_amount")]-balance_row[("pdc/lc_amount")]), data[data.length-1]["currency"]) %}</th>
</tr>
@@ -111,10 +123,10 @@
<th style="width: 4%">{%= __("Age (Days)") %}</th>
{% if(report.report_name === "Accounts Receivable" && filters.show_sales_person_in_print) { %}
<th style="width: 16%">{%= __("Reference") %}</th>
<th style="width: 14%">{%= __("Reference") %}</th>
<th style="width: 10%">{%= __("Sales Person") %}</th>
{% } else { %}
<th style="width: 26%">{%= __("Reference") %}</th>
<th style="width: 24%">{%= __("Reference") %}</th>
{% } %}
{% if(!filters.show_pdc_in_print) { %}
<th style="width: 20%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
@@ -127,7 +139,7 @@
<th style="width: 10%; text-align: right">{%= __("Outstanding Amount") %}</th>
{% if(filters.show_pdc_in_print) { %}
{% if(report.report_name === "Accounts Receivable") { %}
<th style="width: 10%">{%= __("Customer LPO No.") %}</th>
<th style="width: 12%">{%= __("Customer LPO No.") %}</th>
{% } %}
<th style="width: 10%">{%= __("PDC/LC Ref") %}</th>
<th style="width: 10%">{%= __("PDC/LC Amount") %}</th>

View File

@@ -44,6 +44,13 @@ frappe.query_reports["Accounts Receivable"] = {
"default": "90",
"reqd": 1
},
{
"fieldname":"range4",
"label": __("Ageing Range 4"),
"fieldtype": "Int",
"default": "120",
"reqd": 1
},
{
"fieldname":"finance_book",
"label": __("Finance Book"),

View File

@@ -68,13 +68,13 @@ class ReceivablePayableReport(object):
if self.filters.based_on_payment_terms:
columns.append({
"label": "Payment Term",
"label": _("Payment Term"),
"fieldname": "payment_term",
"fieldtype": "Data",
"width": 120
})
columns.append({
"label": "Invoice Grand Total",
"label": _("Invoice Grand Total"),
"fieldname": "invoice_grand_total",
"fieldtype": "Currency",
"options": "currency",
@@ -83,7 +83,7 @@ class ReceivablePayableReport(object):
for label in ("Invoiced Amount", "Paid Amount", credit_or_debit_note, "Outstanding Amount"):
columns.append({
"label": label,
"label": _(label),
"fieldname": frappe.scrub(label),
"fieldtype": "Currency",
"options": "currency",
@@ -100,11 +100,14 @@ class ReceivablePayableReport(object):
self.filters["range2"] = "60"
if not "range3" in self.filters:
self.filters["range3"] = "90"
if not "range4" in self.filters:
self.filters["range4"] = "120"
for label in ("0-{range1}".format(range1=self.filters["range1"]),
"{range1}-{range2}".format(range1=cint(self.filters["range1"])+ 1, range2=self.filters["range2"]),
"{range2}-{range3}".format(range2=cint(self.filters["range2"])+ 1, range3=self.filters["range3"]),
"{range3}-{above}".format(range3=cint(self.filters["range3"])+ 1, above=_("Above"))):
"{range3}-{range4}".format(range3=cint(self.filters["range3"])+ 1, range4=self.filters["range4"]),
"{range4}-{above}".format(range4=cint(self.filters["range4"])+ 1, above=_("Above"))):
columns.append({
"label": label,
"fieldname":label,
@@ -328,18 +331,17 @@ class ReceivablePayableReport(object):
entry_date = gle.posting_date
row += get_ageing_data(cint(self.filters.range1), cint(self.filters.range2),
cint(self.filters.range3), self.age_as_on, entry_date, outstanding_amount)
cint(self.filters.range3), cint(self.filters.range4), self.age_as_on, entry_date, outstanding_amount)
# issue 6371-Ageing buckets should not have amounts if due date is not reached
if self.filters.ageing_based_on == "Due Date" \
and getdate(due_date) > getdate(self.filters.report_date):
row[-1]=row[-2]=row[-3]=row[-4]=0
row[-1]=row[-2]=row[-3]=row[-4]=row[-5]=0
if self.filters.ageing_based_on == "Supplier Invoice Date" \
and getdate(bill_date) > getdate(self.filters.report_date):
row[-1]=row[-2]=row[-3]=row[-4]=0
row[-1]=row[-2]=row[-3]=row[-4]=row[-5]=0
if self.filters.get(scrub(args.get("party_type"))):
row.append(gle.account_currency)
@@ -585,13 +587,13 @@ class ReceivablePayableReport(object):
return payment_term_map
def get_chart_data(self, columns, data):
ageing_columns = columns[self.ageing_col_idx_start : self.ageing_col_idx_start+4]
ageing_columns = columns[self.ageing_col_idx_start : self.ageing_col_idx_start+5]
rows = []
for d in data:
rows.append(
{
'values': d[self.ageing_col_idx_start : self.ageing_col_idx_start+4]
'values': d[self.ageing_col_idx_start : self.ageing_col_idx_start+5]
}
)
@@ -610,21 +612,22 @@ def execute(filters=None):
}
return ReceivablePayableReport(filters).run(args)
def get_ageing_data(first_range, second_range, third_range, age_as_on, entry_date, outstanding_amount):
# [0-30, 30-60, 60-90, 90-above]
outstanding_range = [0.0, 0.0, 0.0, 0.0]
def get_ageing_data(first_range, second_range, third_range,
fourth_range, age_as_on, entry_date, outstanding_amount):
# [0-30, 30-60, 60-90, 90-120, 120-above]
outstanding_range = [0.0, 0.0, 0.0, 0.0, 0.0]
if not (age_as_on and entry_date):
return [0] + outstanding_range
age = (getdate(age_as_on) - getdate(entry_date)).days or 0
index = None
for i, days in enumerate([first_range, second_range, third_range]):
for i, days in enumerate([first_range, second_range, third_range, fourth_range]):
if age <= days:
index = i
break
if index is None: index = 3
if index is None: index = 4
outstanding_range[index] = outstanding_amount
return [age] + outstanding_range

View File

@@ -44,6 +44,13 @@ frappe.query_reports["Accounts Receivable Summary"] = {
"default": "90",
"reqd": 1
},
{
"fieldname":"range4",
"label": __("Ageing Range 4"),
"fieldtype": "Int",
"default": "120",
"reqd": 1
},
{
"fieldname":"finance_book",
"label": __("Finance Book"),

View File

@@ -82,8 +82,15 @@ class AccountsReceivableSummary(ReceivablePayableReport):
"width": 160
},
{
"label": _(str(self.filters.range3) + _("-Above")),
"fieldname": scrub(str(self.filters.range3) + _("-Above")),
"label": _(str(self.filters.range3) + "-" + str(self.filters.range4)),
"fieldname": scrub(str(self.filters.range3) + "-" + str(self.filters.range4)),
"fieldtype": "Currency",
"options": "currency",
"width": 160
},
{
"label": _(str(self.filters.range4) + _("-Above")),
"fieldname": scrub(str(self.filters.range4) + _("-Above")),
"fieldtype": "Currency",
"options": "currency",
"width": 160
@@ -152,7 +159,7 @@ class AccountsReceivableSummary(ReceivablePayableReport):
row += [
party_dict.invoiced_amt, paid_amt, party_dict.credit_amt, party_dict.outstanding_amt,
party_dict.range1, party_dict.range2, party_dict.range3, party_dict.range4,
party_dict.range1, party_dict.range2, party_dict.range3, party_dict.range4, party_dict.range5
]
if args.get("party_type") == "Customer":
@@ -178,6 +185,7 @@ class AccountsReceivableSummary(ReceivablePayableReport):
"range2": 0,
"range3": 0,
"range4": 0,
"range5": 0,
"sales_person": []
})
)
@@ -209,7 +217,7 @@ class AccountsReceivableSummary(ReceivablePayableReport):
cols += ["bill_no", "bill_date"]
cols += ["invoiced_amt", "paid_amt", "credit_amt",
"outstanding_amt", "age", "range1", "range2", "range3", "range4", "currency", "pdc/lc_date", "pdc/lc_ref",
"outstanding_amt", "age", "range1", "range2", "range3", "range4", "range5", "currency", "pdc/lc_date", "pdc/lc_ref",
"pdc/lc_amount"]
if args.get("party_type") == "Supplier":

View File

@@ -10,4 +10,10 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
"fieldtype": "Check",
"default": 1
});
frappe.query_reports["Balance Sheet"]["filters"].push({
"fieldname": "include_default_book_entries",
"label": __("Include Default Book Entries"),
"fieldtype": "Check"
});
});

View File

@@ -45,8 +45,8 @@ def execute(filters=None):
if(filters.get("show_cumulative")):
last_total = period_data[0] - period_data[1]
period_data[2] = period_data[0] - period_data[1]
period_data[2] = period_data[0] - period_data[1]
row += period_data
totals[2] = totals[0] - totals[1]
if filters["period"] != "Yearly" :
@@ -60,7 +60,7 @@ def validate_filters(filters):
frappe.throw(_("Filter based on Cost Center is only applicable if Budget Against is selected as Cost Center"))
def get_columns(filters):
columns = [_(filters.get("budget_against")) + ":Link/%s:80"%(filters.get("budget_against")), _("Account") + ":Link/Account:80"]
columns = [_(filters.get("budget_against")) + ":Link/%s:150"%(filters.get("budget_against")), _("Account") + ":Link/Account:150"]
group_months = False if filters["period"] == "Monthly" else True
@@ -71,7 +71,7 @@ def get_columns(filters):
if filters["period"] == "Yearly":
labels = [_("Budget") + " " + str(year[0]), _("Actual ") + " " + str(year[0]), _("Varaiance ") + " " + str(year[0])]
for label in labels:
columns.append(label+":Float:80")
columns.append(label+":Float:150")
else:
for label in [_("Budget") + " (%s)" + " " + str(year[0]), _("Actual") + " (%s)" + " " + str(year[0]), _("Variance") + " (%s)" + " " + str(year[0])]:
if group_months:
@@ -79,20 +79,20 @@ def get_columns(filters):
else:
label = label % formatdate(from_date, format_string="MMM")
columns.append(label+":Float:80")
columns.append(label+":Float:150")
if filters["period"] != "Yearly" :
return columns + [_("Total Budget") + ":Float:80", _("Total Actual") + ":Float:80",
_("Total Variance") + ":Float:80"]
return columns + [_("Total Budget") + ":Float:150", _("Total Actual") + ":Float:150",
_("Total Variance") + ":Float:150"]
else:
return columns
def get_cost_centers(filters):
cond = "and 1=1"
if filters.get("budget_against") == "Cost Center":
cond = "order by lft"
return frappe.db.sql_list("""select name from `tab{tab}` where company=%s
return frappe.db.sql_list("""select name from `tab{tab}` where company=%s
{cond}""".format(tab=filters.get("budget_against"), cond=cond), filters.get("company"))
#Get cost center & target details
@@ -109,7 +109,7 @@ def get_cost_center_target_details(filters):
""".format(budget_against=filters.get("budget_against").replace(" ", "_").lower(), cond=cond),
(filters.from_fiscal_year,filters.to_fiscal_year,filters.budget_against, filters.company), as_dict=True)
#Get target distribution details of accounts of cost center
def get_target_distribution_details(filters):
@@ -118,7 +118,7 @@ def get_target_distribution_details(filters):
from `tabMonthly Distribution Percentage` mdp, `tabMonthly Distribution` md
where mdp.parent=md.name and md.fiscal_year between %s and %s order by md.fiscal_year""",(filters.from_fiscal_year, filters.to_fiscal_year), as_dict=1):
target_details.setdefault(d.name, {}).setdefault(d.month, flt(d.percentage_allocation))
return target_details
#Get actual details from gl entry
@@ -129,7 +129,7 @@ def get_actual_details(name, filters):
if filters.get("budget_against") == "Cost Center":
cc_lft, cc_rgt = frappe.db.get_value("Cost Center", name, ["lft", "rgt"])
cond = "lft>='{lft}' and rgt<='{rgt}'".format(lft = cc_lft, rgt=cc_rgt)
ac_details = frappe.db.sql("""select gl.account, gl.debit, gl.credit,gl.fiscal_year,
MONTHNAME(gl.posting_date) as month_name, b.{budget_against} as budget_against
from `tabGL Entry` gl, `tabBudget Account` ba, `tabBudget` b
@@ -159,7 +159,7 @@ def get_cost_center_account_month_map(filters):
for ccd in cost_center_target_details:
actual_details = get_actual_details(ccd.budget_against, filters)
for month_id in range(1, 13):
month = datetime.date(2013, month_id, 1).strftime('%B')
cam_map.setdefault(ccd.budget_against, {}).setdefault(ccd.account, {}).setdefault(ccd.fiscal_year,{})\
@@ -172,7 +172,7 @@ def get_cost_center_account_month_map(filters):
if ccd.monthly_distribution else 100.0/12
tav_dict.target = flt(ccd.budget_amount) * month_percentage / 100
for ad in actual_details.get(ccd.account, []):
if ad.month_name == month:
tav_dict.actual += flt(ad.debit) - flt(ad.credit)

View File

@@ -15,4 +15,10 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
"label": __("Accumulated Values"),
"fieldtype": "Check"
});
frappe.query_reports["Cash Flow"]["filters"].push({
"fieldname": "include_default_book_entries",
"label": __("Include Default Book Entries"),
"fieldtype": "Check"
});
});

View File

@@ -14,8 +14,8 @@ def execute(filters=None):
if cint(frappe.db.get_single_value('Accounts Settings', 'use_custom_cash_flow')):
from erpnext.accounts.report.cash_flow.custom_cash_flow import execute as execute_custom
return execute_custom(filters=filters)
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
filters.periodicity, filters.accumulated_values, filters.company)
cash_flow_accounts = get_cash_flow_accounts()
@@ -25,18 +25,18 @@ def execute(filters=None):
accumulated_values=filters.accumulated_values, ignore_closing_entries=True, ignore_accumulated_values_for_fy= True)
expense = get_data(filters.company, "Expense", "Debit", period_list, filters=filters,
accumulated_values=filters.accumulated_values, ignore_closing_entries=True, ignore_accumulated_values_for_fy= True)
net_profit_loss = get_net_profit_loss(income, expense, period_list, filters.company)
data = []
company_currency = frappe.get_cached_value('Company', filters.company, "default_currency")
for cash_flow_account in cash_flow_accounts:
section_data = []
data.append({
"account_name": cash_flow_account['section_header'],
"account_name": cash_flow_account['section_header'],
"parent_account": None,
"indent": 0.0,
"indent": 0.0,
"account": cash_flow_account['section_header']
})
@@ -44,18 +44,18 @@ def execute(filters=None):
# add first net income in operations section
if net_profit_loss:
net_profit_loss.update({
"indent": 1,
"indent": 1,
"parent_account": cash_flow_accounts[0]['section_header']
})
data.append(net_profit_loss)
section_data.append(net_profit_loss)
for account in cash_flow_account['account_types']:
account_data = get_account_type_based_data(filters.company,
account['account_type'], period_list, filters.accumulated_values)
account_data = get_account_type_based_data(filters.company,
account['account_type'], period_list, filters.accumulated_values, filters)
account_data.update({
"account_name": account['label'],
"account": account['label'],
"account": account['label'],
"indent": 1,
"parent_account": cash_flow_account['section_header'],
"currency": company_currency
@@ -63,7 +63,7 @@ def execute(filters=None):
data.append(account_data)
section_data.append(account_data)
add_total_row_account(data, section_data, cash_flow_account['section_footer'],
add_total_row_account(data, section_data, cash_flow_account['section_footer'],
period_list, company_currency)
add_total_row_account(data, data, _("Net Change in Cash"), period_list, company_currency)
@@ -105,13 +105,15 @@ def get_cash_flow_accounts():
# combine all cash flow accounts for iteration
return [operation_accounts, investing_accounts, financing_accounts]
def get_account_type_based_data(company, account_type, period_list, accumulated_values):
def get_account_type_based_data(company, account_type, period_list, accumulated_values, filters):
data = {}
total = 0
for period in period_list:
start_date = get_start_date(period, accumulated_values, company)
amount = get_account_type_based_gl_data(company, start_date, period['to_date'], account_type)
amount = get_account_type_based_gl_data(company, start_date,
period['to_date'], account_type, filters)
if amount and account_type == "Depreciation":
amount *= -1
@@ -121,14 +123,24 @@ def get_account_type_based_data(company, account_type, period_list, accumulated_
data["total"] = total
return data
def get_account_type_based_gl_data(company, start_date, end_date, account_type):
def get_account_type_based_gl_data(company, start_date, end_date, account_type, filters):
cond = ""
if filters.finance_book:
cond = " and finance_book = '%s'" %(frappe.db.escape(filters.finance_book))
if filters.include_default_book_entries:
company_fb = frappe.db.get_value("Company", company, 'default_finance_book')
cond = """ and finance_book in ('%s', '%s')
""" %(frappe.db.escape(filters.finance_book), frappe.db.escape(company_fb))
gl_sum = frappe.db.sql_list("""
select sum(credit) - sum(debit)
from `tabGL Entry`
where company=%s and posting_date >= %s and posting_date <= %s
and voucher_type != 'Period Closing Voucher'
and account in ( SELECT name FROM tabAccount WHERE account_type = %s)
""", (company, start_date, end_date, account_type))
and account in ( SELECT name FROM tabAccount WHERE account_type = %s) {cond}
""".format(cond=cond), (company, start_date, end_date, account_type))
return gl_sum[0] if gl_sum and gl_sum[0] else 0
@@ -154,7 +166,7 @@ def add_total_row_account(out, data, label, period_list, currency, consolidated
key = period if consolidated else period['key']
total_row.setdefault(key, 0.0)
total_row[key] += row.get(key, 0.0)
total_row.setdefault("total", 0.0)
total_row["total"] += row["total"]

View File

@@ -55,5 +55,10 @@ frappe.query_reports["Consolidated Financial Statement"] = {
"fieldtype": "Check",
"default": 0
},
{
"fieldname": "include_default_book_entries",
"label": __("Include Default Book Entries"),
"fieldtype": "Check"
}
]
}

View File

@@ -355,7 +355,8 @@ def set_gl_entries_by_account(from_date, to_date, root_lft, root_rgt, filters, g
"lft": root_lft,
"rgt": root_rgt,
"company": d.name,
"finance_book": filters.get("finance_book")
"finance_book": filters.get("finance_book"),
"company_fb": frappe.db.get_value("Company", d.name, 'default_finance_book')
},
as_dict=True)
@@ -386,7 +387,10 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters):
additional_conditions.append("gl.posting_date >= %(from_date)s")
if filters.get("finance_book"):
additional_conditions.append("ifnull(finance_book, '') in (%(finance_book)s, '')")
if filters.get("include_default_book_entries"):
additional_conditions.append("finance_book in (%(finance_book)s, %(company_fb)s)")
else:
additional_conditions.append("finance_book in (%(finance_book)s)")
return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else ""

View File

@@ -39,7 +39,7 @@
</tr>
</thead>
<tbody>
{% for(var j=0, k=data.length; j<k; j++) { %}
{% for(var j=0, k=data.length-1; j<k; j++) { %}
{%
var row = data[j];
var row_class = data[j].parent_account ? "" : "financial-statements-important";

View File

@@ -321,7 +321,10 @@ def sort_accounts(accounts, is_root=False, key="name"):
"""Sort root types as Asset, Liability, Equity, Income, Expense"""
def compare_accounts(a, b):
if is_root:
if re.split('\W+', a[key])[0].isdigit():
# if chart of accounts is numbered, then sort by number
return cmp(a[key], b[key])
elif is_root:
if a.report_type != b.report_type and a.report_type == "Balance Sheet":
return -1
if a.root_type != b.root_type and a.root_type == "Asset":
@@ -330,10 +333,6 @@ def sort_accounts(accounts, is_root=False, key="name"):
return -1
if a.root_type == "Income" and b.root_type == "Expense":
return -1
else:
if re.split('\W+', a[key])[0].isdigit():
# if chart of accounts is numbered, then sort by number
return cmp(a[key], b[key])
return 1
accounts.sort(key = functools.cmp_to_key(compare_accounts))
@@ -360,7 +359,8 @@ def set_gl_entries_by_account(
"to_date": to_date,
"cost_center": filters.cost_center,
"project": filters.project,
"finance_book": filters.get("finance_book")
"finance_book": filters.get("finance_book"),
"company_fb": frappe.db.get_value("Company", company, 'default_finance_book')
},
as_dict=True)
@@ -394,7 +394,10 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters):
additional_conditions.append("cost_center in %(cost_center)s")
if filters.get("finance_book"):
additional_conditions.append("ifnull(finance_book, '') in (%(finance_book)s, '')")
if filters.get("include_default_book_entries"):
additional_conditions.append("finance_book in (%(finance_book)s, %(company_fb)s)")
else:
additional_conditions.append("finance_book in (%(finance_book)s)")
return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else ""

View File

@@ -33,7 +33,7 @@
</tr>
</thead>
<tbody>
{% for(var i=0, l=data.length; i<l; i++) { %}
{% for(var i=0, l=data.length-1; i<l; i++) { %}
<tr>
{% if(data[i].posting_date) { %}
<td>{%= frappe.datetime.str_to_user(data[i].posting_date) %}</td>

View File

@@ -211,6 +211,16 @@ frappe.query_reports["General Ledger"] = {
"label": __("Currency"),
"fieldtype": "Select",
"options": erpnext.get_presentation_currency_list()
},
{
"fieldname": "show_opening_entries",
"label": __("Show Opening Entries"),
"fieldtype": "Check"
},
{
"fieldname": "include_default_book_entries",
"label": __("Include Default Book Entries"),
"fieldtype": "Check"
}
]
}

View File

@@ -128,10 +128,15 @@ def get_gl_entries(filters):
if filters.get("group_by") == _("Group by Voucher (Consolidated)"):
group_by_statement = "group by voucher_type, voucher_no, account, cost_center"
select_fields = """, sum(debit) as debit, sum(credit) as credit,
sum(debit_in_account_currency) as debit_in_account_currency,
sum(credit_in_account_currency) as credit_in_account_currency"""
if filters.get("include_default_book_entries"):
filters['company_fb'] = frappe.db.get_value("Company",
filters.get("company"), 'default_finance_book')
gl_entries = frappe.db.sql(
"""
select
@@ -187,7 +192,10 @@ def get_conditions(filters):
conditions.append("project in %(project)s")
if filters.get("finance_book"):
conditions.append("ifnull(finance_book, '') in (%(finance_book)s, '')")
if filters.get("include_default_book_entries"):
conditions.append("finance_book in (%(finance_book)s, %(company_fb)s)")
else:
conditions.append("finance_book in (%(finance_book)s)")
from frappe.desk.reportview import build_match_conditions
match_conditions = build_match_conditions("GL Entry")
@@ -283,7 +291,8 @@ def get_accountwise_gle(filters, gl_entries, gle_map):
from_date, to_date = getdate(filters.from_date), getdate(filters.to_date)
for gle in gl_entries:
if gle.posting_date < from_date or cstr(gle.is_opening) == "Yes":
if (gle.posting_date < from_date or
(cstr(gle.is_opening) == "Yes" and not filters.get("show_opening_entries"))):
update_value_in_dict(gle_map[gle.get(group_by)].totals, 'opening', gle)
update_value_in_dict(totals, 'opening', gle)

View File

@@ -65,7 +65,7 @@ def get_columns(group_wise_columns, filters):
"warehouse": _("Warehouse") + ":Link/Warehouse",
"qty": _("Qty") + ":Float",
"base_rate": _("Avg. Selling Rate") + ":Currency/currency",
"buying_rate": _("Avg. Buying Rate") + ":Currency/currency",
"buying_rate": _("Valuation Rate") + ":Currency/currency",
"base_amount": _("Selling Amount") + ":Currency/currency",
"buying_amount": _("Buying Amount") + ":Currency/currency",
"gross_profit": _("Gross Profit") + ":Currency/currency",

View File

@@ -2,8 +2,15 @@
// For license information, please see license.txt
/* eslint-disable */
frappe.query_reports["Inactive Items"] = {
frappe.query_reports["Inactive Sales Items"] = {
"filters": [
{
fieldname: "territory",
label: __("Territory"),
fieldtype: "Link",
options: "Territory",
reqd: 1,
},
{
fieldname: "item",
label: __("Item"),

View File

@@ -1,21 +1,20 @@
{
"add_total_row": 0,
"creation": "2019-04-16 16:05:00.647308",
"creation": "2019-05-01 12:59:52.018850",
"disable_prepared_report": 0,
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"letter_head": "Test Letter Head 1",
"modified": "2019-04-16 16:06:33.630043",
"modified": "2019-05-01 13:00:26.545278",
"modified_by": "Administrator",
"module": "Stock",
"name": "Inactive Items",
"module": "Accounts",
"name": "Inactive Sales Items",
"owner": "Administrator",
"prepared_report": 0,
"ref_doctype": "Sales Invoice",
"report_name": "Inactive Items",
"report_name": "Inactive Sales Items",
"report_type": "Script Report",
"roles": [
{

View File

@@ -7,13 +7,11 @@ from frappe.utils import getdate, add_days, today, cint
from frappe import _
def execute(filters=None):
columns = get_columns()
data = get_data(filters)
return columns, data
def get_columns():
columns = [
{
"fieldname": "territory",
@@ -30,7 +28,7 @@ def get_columns():
"width": 150
},
{
"fieldname": "item_name",
"fieldname": "item",
"fieldtype": "Link",
"options": "Item",
"label": "Item",
@@ -74,59 +72,68 @@ def get_columns():
def get_data(filters):
data = []
items = get_items(filters)
territories = get_territories(filters)
sales_invoice_data = get_sales_details(filters)
for item in items:
if sales_invoice_data.get(item.name):
item_obj = sales_invoice_data[item.name]
if item_obj.days_since_last_order > cint(filters['days']):
row = {
"territory": item_obj.territory,
"item_group": item_obj.item_group,
"item": item_obj.name,
"item_name": item_obj.item_name,
"customer": item_obj.customer,
"last_order_date": item_obj.last_order_date,
"qty": item_obj.qty,
"days_since_last_order": item_obj.days_since_last_order
}
data.append(row)
else:
for territory in territories:
for item in items:
row = {
"territory": territory.name,
"item_group": item.item_group,
"item": item.name,
"item": item.item_code,
"item_name": item.item_name
}
if sales_invoice_data.get((territory.name,item.item_code)):
item_obj = sales_invoice_data[(territory.name,item.item_code)]
if item_obj.days_since_last_order > cint(filters['days']):
row.update({
"territory": item_obj.territory,
"customer": item_obj.customer,
"last_order_date": item_obj.last_order_date,
"qty": item_obj.qty,
"days_since_last_order": item_obj.days_since_last_order
})
else:
continue
data.append(row)
return data
def get_sales_details(filters):
data = []
item_details_map = {}
date_field = "s.transaction_date" if filters["based_on"] == "Sales Order" else "s.posting_date"
sales_data = frappe.db.sql("""
select s.territory, s.customer, si.item_group, si.item_name, si.qty, {date_field} as last_order_date,
select s.territory, s.customer, si.item_group, si.item_code, si.qty, {date_field} as last_order_date,
DATEDIFF(CURDATE(), {date_field}) as days_since_last_order
from `tab{doctype}` s, `tab{doctype} Item` si
where s.name = si.parent and s.docstatus = 1
group by si.name order by days_since_last_order """ #nosec
order by days_since_last_order """ #nosec
.format(date_field = date_field, doctype = filters['based_on']), as_dict=1)
for d in sales_data:
item_details_map.setdefault(d.item_name, d)
item_details_map.setdefault((d.territory,d.item_code), d)
return item_details_map
def get_items(filters):
def get_territories(filters):
filter_dict = {}
if filters.get("territory"):
filter_dict.update({'name': filters['territory']})
territories = frappe.get_all("Territory", fields=["name"], filters=filter_dict)
return territories
def get_items(filters):
filters_dict = {
"disabled": 0,
"is_stock_item": 1
@@ -142,7 +149,6 @@ def get_items(filters):
"name": filters["item"]
})
items = frappe.get_all("Item", fields=["name", "item_group", "item_name"], filters=filters_dict, order_by="name")
items = frappe.get_all("Item", fields=["name", "item_group", "item_name", "item_code"], filters=filters_dict, order_by="name")
return items

View File

@@ -102,7 +102,9 @@ def get_conditions(filters):
("customer", " and `tabSales Invoice`.customer = %(customer)s"),
("item_code", " and `tabSales Invoice Item`.item_code = %(item_code)s"),
("from_date", " and `tabSales Invoice`.posting_date>=%(from_date)s"),
("to_date", " and `tabSales Invoice`.posting_date<=%(to_date)s")):
("to_date", " and `tabSales Invoice`.posting_date<=%(to_date)s"),
("company_gstin", " and `tabSales Invoice`.company_gstin = %(company_gstin)s"),
("invoice_type", " and `tabSales Invoice`.invoice_type = %(invoice_type)s")):
if filters.get(opts[0]):
conditions += opts[1]

View File

@@ -12,20 +12,21 @@ def get_ordered_to_be_billed_data(args):
child_tab = doctype + " Item"
precision = get_field_precision(frappe.get_meta(child_tab).get_field("billed_amt"),
currency=get_default_currency()) or 2
project_field = get_project_field(doctype, party)
return frappe.db.sql("""
Select
`{parent_tab}`.name, `{parent_tab}`.{date_field}, `{parent_tab}`.{party}, `{parent_tab}`.{party}_name,
{project_field}, `{child_tab}`.item_code, `{child_tab}`.base_amount,
(`{child_tab}`.billed_amt * ifnull(`{parent_tab}`.conversion_rate, 1)),
(`{child_tab}`.billed_amt * ifnull(`{parent_tab}`.conversion_rate, 1)),
(`{child_tab}`.base_amount - (`{child_tab}`.billed_amt * ifnull(`{parent_tab}`.conversion_rate, 1))),
`{child_tab}`.item_name, `{child_tab}`.description, `{parent_tab}`.company
from
`{parent_tab}`, `{child_tab}`
where
`{parent_tab}`.name = `{child_tab}`.parent and `{parent_tab}`.docstatus = 1 and `{parent_tab}`.status != 'Closed'
`{parent_tab}`.name = `{child_tab}`.parent and `{parent_tab}`.docstatus = 1
and `{parent_tab}`.status not in ('Closed', 'Completed')
and `{child_tab}`.amount > 0 and round(`{child_tab}`.billed_amt *
ifnull(`{parent_tab}`.conversion_rate, 1), {precision}) < `{child_tab}`.base_amount
order by

View File

@@ -18,22 +18,22 @@ def execute(filters=None):
data = []
for d in entries:
invoice = invoice_details.get(d.against_voucher) or frappe._dict()
if d.reference_type=="Purchase Invoice":
payment_amount = flt(d.debit) or -1 * flt(d.credit)
else:
payment_amount = flt(d.credit) or -1 * flt(d.debit)
row = [d.voucher_type, d.voucher_no, d.party_type, d.party, d.posting_date, d.against_voucher,
row = [d.voucher_type, d.voucher_no, d.party_type, d.party, d.posting_date, d.against_voucher,
invoice.posting_date, invoice.due_date, d.debit, d.credit, d.remarks]
if d.against_voucher:
row += get_ageing_data(30, 60, 90, d.posting_date, invoice.posting_date, payment_amount)
row += get_ageing_data(30, 60, 90, 120, d.posting_date, invoice.posting_date, payment_amount)
else:
row += ["", "", "", "", ""]
if invoice.due_date:
row.append((getdate(d.posting_date) - getdate(invoice.due_date)).days or 0)
data.append(row)
return columns, data
@@ -48,19 +48,19 @@ def get_columns(filters):
return [
_("Payment Document") + ":: 100",
_("Payment Entry") + ":Dynamic Link/"+_("Payment Document")+":140",
_("Party Type") + "::100",
_("Party Type") + "::100",
_("Party") + ":Dynamic Link/Party Type:140",
_("Posting Date") + ":Date:100",
_("Invoice") + (":Link/Purchase Invoice:130" if filters.get("payment_type") == "Outgoing" else ":Link/Sales Invoice:130"),
_("Invoice Posting Date") + ":Date:130",
_("Payment Due Date") + ":Date:130",
_("Debit") + ":Currency:120",
_("Invoice Posting Date") + ":Date:130",
_("Payment Due Date") + ":Date:130",
_("Debit") + ":Currency:120",
_("Credit") + ":Currency:120",
_("Remarks") + "::150",
_("Remarks") + "::150",
_("Age") +":Int:40",
"0-30:Currency:100",
"30-60:Currency:100",
"60-90:Currency:100",
"0-30:Currency:100",
"30-60:Currency:100",
"60-90:Currency:100",
_("90-Above") + ":Currency:100",
_("Delay in payment (Days)") + "::150"
]
@@ -79,21 +79,21 @@ def get_conditions(filters):
if filters.party:
conditions.append("party=%(party)s")
if filters.party_type:
conditions.append("against_voucher_type=%(reference_type)s")
filters["reference_type"] = "Sales Invoice" if filters.party_type=="Customer" else "Purchase Invoice"
if filters.get("from_date"):
conditions.append("posting_date >= %(from_date)s")
if filters.get("to_date"):
conditions.append("posting_date <= %(to_date)s")
return "and " + " and ".join(conditions) if conditions else ""
def get_entries(filters):
return frappe.db.sql("""select
return frappe.db.sql("""select
voucher_type, voucher_no, party_type, party, posting_date, debit, credit, remarks, against_voucher
from `tabGL Entry`
where company=%(company)s and voucher_type in ('Journal Entry', 'Payment Entry') {0}

View File

@@ -41,6 +41,11 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
"fieldname": "accumulated_values",
"label": __("Accumulated Values"),
"fieldtype": "Check"
},
{
"fieldname": "include_default_book_entries",
"label": __("Include Default Book Entries"),
"fieldtype": "Check"
}
);
});

View File

@@ -93,4 +93,6 @@ def get_chart_data(filters, columns, income, expense, net_profit_loss):
else:
chart["type"] = "line"
chart["fieldtype"] = "Currency"
return chart

View File

@@ -47,8 +47,8 @@ class TestSalesPaymentSummary(unittest.TestCase):
pe.submit()
mop = get_mode_of_payments(filters)
self.assertTrue('Credit Card' in mop.values()[0])
self.assertTrue('Cash' in mop.values()[0])
self.assertTrue('Credit Card' in list(mop.values())[0])
self.assertTrue('Cash' in list(mop.values())[0])
# Cancel all Cash payment entry and check if this mode of payment is still fetched.
payment_entries = frappe.get_all("Payment Entry", filters={"mode_of_payment": "Cash", "docstatus": 1}, fields=["name", "docstatus"])
@@ -57,8 +57,8 @@ class TestSalesPaymentSummary(unittest.TestCase):
pe.cancel()
mop = get_mode_of_payments(filters)
self.assertTrue('Credit Card' in mop.values()[0])
self.assertTrue('Cash' not in mop.values()[0])
self.assertTrue('Credit Card' in list(mop.values())[0])
self.assertTrue('Cash' not in list(mop.values())[0])
def test_get_mode_of_payments_details(self):
filters = get_filters()
@@ -84,7 +84,7 @@ class TestSalesPaymentSummary(unittest.TestCase):
mopd = get_mode_of_payment_details(filters)
mopd_values = mopd.values()[0]
mopd_values = list(mopd.values())[0]
for mopd_value in mopd_values:
if mopd_value[0] == "Credit Card":
cc_init_amount = mopd_value[1]
@@ -96,7 +96,7 @@ class TestSalesPaymentSummary(unittest.TestCase):
pe.cancel()
mopd = get_mode_of_payment_details(filters)
mopd_values = mopd.values()[0]
mopd_values = list(mopd.values())[0]
for mopd_value in mopd_values:
if mopd_value[0] == "Credit Card":
cc_final_amount = mopd_value[1]

View File

@@ -105,7 +105,7 @@ def get_rootwise_opening_balances(filters, report_type):
if filters.finance_book:
fb_conditions = " and finance_book = %(finance_book)s"
if filters.include_default_book_entries:
fb_conditions = " and (finance_book in (%(finance_book)s, %(company_fb)s) or finance_book is null)"
fb_conditions = " and (finance_book in (%(finance_book)s, %(company_fb)s))"
additional_conditions += fb_conditions
@@ -180,20 +180,28 @@ def calculate_values(accounts, gl_entries_by_account, opening_balances, filters,
if d["root_type"] == "Asset" or d["root_type"] == "Equity" or d["root_type"] == "Expense":
d["opening_debit"] -= d["opening_credit"]
d["opening_credit"] = 0.0
total_row["opening_debit"] += d["opening_debit"]
d["closing_debit"] -= d["closing_credit"]
# For opening
check_opening_closing_has_negative_value(d, "opening_debit", "opening_credit")
# For closing
check_opening_closing_has_negative_value(d, "closing_debit", "closing_credit")
if d["root_type"] == "Liability" or d["root_type"] == "Income":
d["opening_credit"] -= d["opening_debit"]
d["opening_debit"] = 0.0
total_row["opening_credit"] += d["opening_credit"]
if d["root_type"] == "Asset" or d["root_type"] == "Equity" or d["root_type"] == "Expense":
d["closing_debit"] -= d["closing_credit"]
d["closing_credit"] = 0.0
total_row["closing_debit"] += d["closing_debit"]
if d["root_type"] == "Liability" or d["root_type"] == "Income":
d["closing_credit"] -= d["closing_debit"]
d["closing_debit"] = 0.0
total_row["closing_credit"] += d["closing_credit"]
# For opening
check_opening_closing_has_negative_value(d, "opening_credit", "opening_debit")
# For closing
check_opening_closing_has_negative_value(d, "closing_credit", "closing_debit")
total_row["opening_debit"] += d["opening_debit"]
total_row["closing_debit"] += d["closing_debit"]
total_row["opening_credit"] += d["opening_credit"]
total_row["closing_credit"] += d["closing_credit"]
return total_row
@@ -219,8 +227,6 @@ def prepare_data(accounts, filters, total_row, parent_children_map, company_curr
if d.account_number else d.account_name)
}
prepare_opening_and_closing(d)
for key in value_fields:
row[key] = flt(d.get(key, 0.0), 3)
@@ -295,22 +301,11 @@ def get_columns():
}
]
def prepare_opening_and_closing(d):
d["closing_debit"] = d["opening_debit"] + d["debit"]
d["closing_credit"] = d["opening_credit"] + d["credit"]
def check_opening_closing_has_negative_value(d, dr_or_cr, switch_to_column):
# If opening debit has negetive value then move it to opening credit and vice versa.
if d["root_type"] == "Asset" or d["root_type"] == "Equity" or d["root_type"] == "Expense":
d["opening_debit"] -= d["opening_credit"]
d["opening_credit"] = 0.0
if d["root_type"] == "Liability" or d["root_type"] == "Income":
d["opening_credit"] -= d["opening_debit"]
d["opening_debit"] = 0.0
if d["root_type"] == "Asset" or d["root_type"] == "Equity" or d["root_type"] == "Expense":
d["closing_debit"] -= d["closing_credit"]
d["closing_credit"] = 0.0
if d["root_type"] == "Liability" or d["root_type"] == "Income":
d["closing_credit"] -= d["closing_debit"]
d["closing_debit"] = 0.0
if d[dr_or_cr] < 0:
d[switch_to_column] = abs(d[dr_or_cr])
d[dr_or_cr] = 0.0
else:
d[switch_to_column] = 0.0

View File

@@ -137,7 +137,7 @@ def get_appropriate_company(filters):
return company
@frappe.whitelist()
def get_invoiced_item_gross_margin(sales_invoice=None, item_code=None, company=None):
def get_invoiced_item_gross_margin(sales_invoice=None, item_code=None, company=None, with_item_data=False):
from erpnext.accounts.report.gross_profit.gross_profit import GrossProfitGenerator
sales_invoice = sales_invoice or frappe.form_dict.get('sales_invoice')
@@ -152,5 +152,8 @@ def get_invoiced_item_gross_margin(sales_invoice=None, item_code=None, company=N
}
gross_profit_data = GrossProfitGenerator(filters)
result = gross_profit_data.grouped_data
if not with_item_data:
result = sum([d.gross_profit for d in result])
return gross_profit_data.grouped_data
return result

View File

@@ -333,6 +333,9 @@ def reconcile_against_document(args):
doc = frappe.get_doc(d.voucher_type, d.voucher_no)
doc.make_gl_entries(cancel = 0, adv_adj =1)
if d.voucher_type in ('Payment Entry', 'Journal Entry'):
doc.update_expense_claim()
def check_if_advance_entry_modified(args):
"""
check if there is already a voucher reference
@@ -375,9 +378,9 @@ def check_if_advance_entry_modified(args):
def validate_allocated_amount(args):
if args.get("allocated_amount") < 0:
throw(_("Allocated amount can not be negative"))
throw(_("Allocated amount cannot be negative"))
elif args.get("allocated_amount") > args.get("unadjusted_amount"):
throw(_("Allocated amount can not greater than unadjusted amount"))
throw(_("Allocated amount cannot be greater than unadjusted amount"))
def update_reference_in_journal_entry(d, jv_obj):
"""

View File

@@ -6,7 +6,6 @@ from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.model.document import Document
from frappe import _
class Disease(Document):
def validate(self):

View File

@@ -7,7 +7,6 @@ import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils import flt, cint
from frappe import _
class SoilTexture(Document):
soil_edit_order = [2, 1, 0]
@@ -35,8 +34,8 @@ class SoilTexture(Document):
if sum(self.soil_edit_order) < 5: return
last_edit_index = self.soil_edit_order.index(min(self.soil_edit_order))
# set composition of the last edited soil
self.set( self.soil_types[last_edit_index],
# set composition of the last edited soil
self.set( self.soil_types[last_edit_index],
100 - sum(cint(self.get(soil_type)) for soil_type in self.soil_types) + cint(self.get(self.soil_types[last_edit_index])))
# calculate soil type

View File

@@ -6,7 +6,6 @@ from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.model.document import Document
from frappe import _
class WaterAnalysis(Document):
def load_contents(self):

View File

@@ -291,16 +291,19 @@ class Asset(AccountsController):
def validate_expected_value_after_useful_life(self):
for row in self.get('finance_books'):
accumulated_depreciation_after_full_schedule = max([d.accumulated_depreciation_amount
for d in self.get("schedules") if cint(d.finance_book_id) == row.idx])
accumulated_depreciation_after_full_schedule = [d.accumulated_depreciation_amount
for d in self.get("schedules") if cint(d.finance_book_id) == row.idx]
asset_value_after_full_schedule = flt(flt(self.gross_purchase_amount) -
flt(accumulated_depreciation_after_full_schedule),
self.precision('gross_purchase_amount'))
if accumulated_depreciation_after_full_schedule:
accumulated_depreciation_after_full_schedule = max(accumulated_depreciation_after_full_schedule)
if row.expected_value_after_useful_life < asset_value_after_full_schedule:
frappe.throw(_("Depreciation Row {0}: Expected value after useful life must be greater than or equal to {1}")
.format(row.idx, asset_value_after_full_schedule))
asset_value_after_full_schedule = flt(flt(self.gross_purchase_amount) -
flt(accumulated_depreciation_after_full_schedule),
self.precision('gross_purchase_amount'))
if row.expected_value_after_useful_life < asset_value_after_full_schedule:
frappe.throw(_("Depreciation Row {0}: Expected value after useful life must be greater than or equal to {1}")
.format(row.idx, asset_value_after_full_schedule))
def validate_cancellation(self):
if self.status not in ("Submitted", "Partially Depreciated", "Fully Depreciated"):

View File

@@ -36,7 +36,7 @@ def make_depreciation_entry(asset_name, date=None):
fixed_asset_account, accumulated_depreciation_account, depreciation_expense_account = \
get_depreciation_accounts(asset)
depreciation_cost_center, depreciation_series = frappe.get_cached_value('Company', asset.company,
depreciation_cost_center, depreciation_series = frappe.get_cached_value('Company', asset.company,
["depreciation_cost_center", "series_for_depreciation_entry"])
depreciation_cost_center = asset.cost_center or depreciation_cost_center
@@ -70,7 +70,7 @@ def make_depreciation_entry(asset_name, date=None):
je.submit()
d.db_set("journal_entry", je.name)
idx = cint(d.finance_book_id)
finance_books = asset.get('finance_books')[idx - 1]
finance_books.value_after_depreciation -= d.depreciation_amount
@@ -88,15 +88,15 @@ def get_depreciation_accounts(asset):
fieldname = ['fixed_asset_account', 'accumulated_depreciation_account',
'depreciation_expense_account'], as_dict=1)
if accounts:
if accounts:
fixed_asset_account = accounts.fixed_asset_account
accumulated_depreciation_account = accounts.accumulated_depreciation_account
depreciation_expense_account = accounts.depreciation_expense_account
if not accumulated_depreciation_account or not depreciation_expense_account:
accounts = frappe.get_cached_value('Company', asset.company,
accounts = frappe.get_cached_value('Company', asset.company,
["accumulated_depreciation_account", "depreciation_expense_account"])
if not accumulated_depreciation_account:
accumulated_depreciation_account = accounts[0]
if not depreciation_expense_account:
@@ -135,11 +135,11 @@ def scrap_asset(asset_name):
je.flags.ignore_permissions = True
je.submit()
frappe.db.set_value("Asset", asset_name, "disposal_date", today())
frappe.db.set_value("Asset", asset_name, "journal_entry_for_scrap", je.name)
asset.set_status("Scrapped")
frappe.msgprint(_("Asset scrapped via Journal Entry {0}").format(je.name))
@frappe.whitelist()
@@ -147,21 +147,29 @@ def restore_asset(asset_name):
asset = frappe.get_doc("Asset", asset_name)
je = asset.journal_entry_for_scrap
asset.db_set("disposal_date", None)
asset.db_set("journal_entry_for_scrap", None)
frappe.get_doc("Journal Entry", je).cancel()
asset.set_status()
@frappe.whitelist()
def get_gl_entries_on_asset_disposal(asset, selling_amount=0):
def get_gl_entries_on_asset_disposal(asset, selling_amount=0, finance_book=None):
fixed_asset_account, accumulated_depr_account, depr_expense_account = get_depreciation_accounts(asset)
disposal_account, depreciation_cost_center = get_disposal_account_and_cost_center(asset.company)
depreciation_cost_center = asset.cost_center or depreciation_cost_center
accumulated_depr_amount = flt(asset.gross_purchase_amount) - flt(asset.value_after_depreciation)
idx = 1
if finance_book:
for d in asset.finance_books:
if d.finance_book == finance_book:
idx = d.idx
break
value_after_depreciation = asset.finance_books[idx - 1].value_after_depreciation
accumulated_depr_amount = flt(asset.gross_purchase_amount) - flt(value_after_depreciation)
gl_entries = [
{
@@ -176,7 +184,7 @@ def get_gl_entries_on_asset_disposal(asset, selling_amount=0):
}
]
profit_amount = flt(selling_amount) - flt(asset.value_after_depreciation)
profit_amount = flt(selling_amount) - flt(value_after_depreciation)
if profit_amount:
debit_or_credit = "debit" if profit_amount < 0 else "credit"
gl_entries.append({
@@ -190,7 +198,7 @@ def get_gl_entries_on_asset_disposal(asset, selling_amount=0):
@frappe.whitelist()
def get_disposal_account_and_cost_center(company):
disposal_account, depreciation_cost_center = frappe.get_cached_value('Company', company,
disposal_account, depreciation_cost_center = frappe.get_cached_value('Company', company,
["disposal_account", "depreciation_cost_center"])
if not disposal_account:

View File

@@ -366,8 +366,9 @@ class TestAsset(unittest.TestCase):
self.assertTrue(asset.journal_entry_for_scrap)
expected_gle = (
("_Test Accumulated Depreciations - _TC", 100000.0, 0.0),
("_Test Fixed Asset - _TC", 0.0, 100000.0)
("_Test Accumulated Depreciations - _TC", 147.54, 0.0),
("_Test Fixed Asset - _TC", 0.0, 100000.0),
("_Test Gain/Loss on Asset Disposal - _TC", 99852.46, 0.0)
)
gle = frappe.db.sql("""select account, debit, credit from `tabGL Entry`
@@ -411,9 +412,9 @@ class TestAsset(unittest.TestCase):
self.assertEqual(frappe.db.get_value("Asset", asset.name, "status"), "Sold")
expected_gle = (
("_Test Accumulated Depreciations - _TC", 100000.0, 0.0),
("_Test Accumulated Depreciations - _TC", 23051.47, 0.0),
("_Test Fixed Asset - _TC", 0.0, 100000.0),
("_Test Gain/Loss on Asset Disposal - _TC", 0, 25000.0),
("_Test Gain/Loss on Asset Disposal - _TC", 51948.53, 0.0),
("Debtors - _TC", 25000.0, 0.0)
)

View File

@@ -36,7 +36,7 @@ class AssetValueAdjustment(Document):
fixed_asset_account, accumulated_depreciation_account, depreciation_expense_account = \
get_depreciation_accounts(asset)
depreciation_cost_center, depreciation_series = frappe.get_cached_value('Company', asset.company,
depreciation_cost_center, depreciation_series = frappe.get_cached_value('Company', asset.company,
["depreciation_cost_center", "series_for_depreciation_entry"])
je = frappe.new_doc("Journal Entry")
@@ -75,8 +75,8 @@ class AssetValueAdjustment(Document):
rate_per_day = flt(d.value_after_depreciation) / flt(total_days)
from_date = self.date
else:
no_of_depreciations = len([e.name for e in asset.schedules
if (cint(s.finance_book_id) == d.idx and not e.journal_entry)])
no_of_depreciations = len([s.name for s in asset.schedules
if (cint(s.finance_book_id) == d.idx and not s.journal_entry)])
value_after_depreciation = d.value_after_depreciation
for data in asset.schedules:

View File

@@ -25,9 +25,12 @@ class TestLocation(unittest.TestCase):
temp['features'][0]['properties']['feature_of'] = location
formatted_locations.extend(temp['features'])
formatted_location_string = str(formatted_locations)
test_location = frappe.get_doc('Location', 'Test Location Area')
test_location.save()
self.assertEqual(formatted_location_string, str(json.loads(test_location.get('location'))['features']))
test_location_features = json.loads(test_location.get('location'))['features']
ordered_test_location_features = sorted(test_location_features, key=lambda x: x['properties']['feature_of'])
ordered_formatted_locations = sorted(formatted_locations, key=lambda x: x['properties']['feature_of'])
self.assertEqual(ordered_formatted_locations, ordered_test_location_features)
self.assertEqual(area, test_location.get('area'))

View File

@@ -33,6 +33,14 @@ frappe.ui.form.on("Purchase Order", {
}
}
});
frm.set_query("expense_account", "items", function() {
return {
query: "erpnext.controllers.queries.get_expense_account",
filters: {'company': frm.doc.company}
}
});
},
refresh: function(frm) {
@@ -96,7 +104,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
if(doc.docstatus == 1 && !in_list(["Closed", "Delivered"], doc.status)) {
if (this.frm.has_perm("submit")) {
if(flt(doc.per_billed, 2) < 100 || doc.per_received < 100) {
if(flt(doc.per_billed, 6) < 100 || flt(doc.per_received, 6) < 100) {
cur_frm.add_custom_button(__('Close'), this.close_purchase_order, __("Status"));
}
}

View File

@@ -20,6 +20,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "supplier_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -53,6 +54,7 @@
"collapsible": 0,
"columns": 0,
"default": "{supplier_name}",
"fetch_if_empty": 0,
"fieldname": "title",
"fieldtype": "Data",
"hidden": 1,
@@ -86,6 +88,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
"fetch_if_empty": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
@@ -121,6 +124,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
"fetch_if_empty": 0,
"fieldname": "supplier",
"fieldtype": "Link",
"hidden": 0,
@@ -156,6 +160,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.supplier && doc.docstatus===0 && (!(doc.items && doc.items.length) || (doc.items.length==1 && !doc.items[0].item_code))",
"fetch_if_empty": 0,
"fieldname": "get_items_from_open_material_requests",
"fieldtype": "Button",
"hidden": 0,
@@ -189,6 +194,7 @@
"collapsible": 0,
"columns": 0,
"fetch_from": "supplier.supplier_name",
"fetch_if_empty": 0,
"fieldname": "supplier_name",
"fieldtype": "Data",
"hidden": 0,
@@ -222,6 +228,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
"fetch_if_empty": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -256,6 +263,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
@@ -290,6 +298,7 @@
"collapsible": 0,
"columns": 0,
"default": "Today",
"fetch_if_empty": 0,
"fieldname": "transaction_date",
"fieldtype": "Date",
"hidden": 0,
@@ -324,6 +333,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
"fetch_if_empty": 0,
"fieldname": "schedule_date",
"fieldtype": "Date",
"hidden": 0,
@@ -357,6 +367,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.docstatus===1",
"fetch_if_empty": 0,
"fieldname": "order_confirmation_no",
"fieldtype": "Data",
"hidden": 0,
@@ -390,6 +401,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.order_confirmation_no",
"fetch_if_empty": 0,
"fieldname": "order_confirmation_date",
"fieldtype": "Date",
"hidden": 0,
@@ -422,6 +434,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@@ -457,6 +470,7 @@
"collapsible": 0,
"collapsible_depends_on": "",
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "drop_ship",
"fieldtype": "Section Break",
"hidden": 0,
@@ -490,6 +504,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fetch_if_empty": 0,
"fieldname": "customer",
"fieldtype": "Link",
"hidden": 0,
@@ -524,6 +539,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fetch_if_empty": 0,
"fieldname": "customer_name",
"fieldtype": "Data",
"hidden": 0,
@@ -556,6 +572,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_19",
"fieldtype": "Column Break",
"hidden": 0,
@@ -588,6 +605,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fetch_if_empty": 0,
"fieldname": "customer_contact_person",
"fieldtype": "Link",
"hidden": 0,
@@ -621,6 +639,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "customer_contact_display",
"fieldtype": "Small Text",
"hidden": 1,
@@ -653,6 +672,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "customer_contact_mobile",
"fieldtype": "Small Text",
"hidden": 1,
@@ -685,6 +705,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "customer_contact_email",
"fieldtype": "Code",
"hidden": 1,
@@ -718,6 +739,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "section_addresses",
"fieldtype": "Section Break",
"hidden": 0,
@@ -750,6 +772,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "supplier_address",
"fieldtype": "Link",
"hidden": 0,
@@ -782,6 +805,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "contact_person",
"fieldtype": "Link",
"hidden": 0,
@@ -815,6 +839,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fetch_if_empty": 0,
"fieldname": "address_display",
"fieldtype": "Small Text",
"hidden": 0,
@@ -846,6 +871,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "contact_display",
"fieldtype": "Small Text",
"hidden": 0,
@@ -877,6 +903,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "contact_mobile",
"fieldtype": "Small Text",
"hidden": 0,
@@ -908,6 +935,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "contact_email",
"fieldtype": "Small Text",
"hidden": 0,
@@ -939,6 +967,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "col_break_address",
"fieldtype": "Column Break",
"hidden": 0,
@@ -971,6 +1000,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fetch_if_empty": 0,
"fieldname": "shipping_address",
"fieldtype": "Link",
"hidden": 0,
@@ -1004,6 +1034,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "shipping_address_display",
"fieldtype": "Small Text",
"hidden": 0,
@@ -1036,6 +1067,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "currency_and_price_list",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1068,6 +1100,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "currency",
"fieldtype": "Link",
"hidden": 0,
@@ -1103,6 +1136,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
"fetch_if_empty": 0,
"fieldname": "conversion_rate",
"fieldtype": "Float",
"hidden": 0,
@@ -1137,6 +1171,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "cb_price_list",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1167,6 +1202,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "buying_price_list",
"fieldtype": "Link",
"hidden": 0,
@@ -1199,6 +1235,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "price_list_currency",
"fieldtype": "Link",
"hidden": 0,
@@ -1231,6 +1268,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "plc_conversion_rate",
"fieldtype": "Float",
"hidden": 0,
@@ -1263,6 +1301,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "ignore_pricing_rule",
"fieldtype": "Check",
"hidden": 0,
@@ -1294,6 +1333,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "sec_warehouse",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1325,6 +1365,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "set_warehouse",
"fieldtype": "Link",
"hidden": 0,
@@ -1358,6 +1399,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "col_break_warehouse",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1390,6 +1432,7 @@
"collapsible": 0,
"columns": 0,
"default": "No",
"fetch_if_empty": 0,
"fieldname": "is_subcontracted",
"fieldtype": "Select",
"hidden": 0,
@@ -1423,6 +1466,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.is_subcontracted==\"Yes\"",
"fetch_if_empty": 0,
"fieldname": "supplier_warehouse",
"fieldtype": "Link",
"hidden": 0,
@@ -1456,6 +1500,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "items_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1489,6 +1534,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "scan_barcode",
"fieldtype": "Data",
"hidden": 0,
@@ -1521,6 +1567,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "items",
"fieldtype": "Table",
"hidden": 0,
@@ -1556,6 +1603,7 @@
"collapsible": 0,
"collapsible_depends_on": "supplied_items",
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "raw_material_details",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1589,6 +1637,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fetch_if_empty": 0,
"fieldname": "supplied_items",
"fieldtype": "Table",
"hidden": 0,
@@ -1623,6 +1672,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "sb_last_purchase",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1653,6 +1703,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "total_qty",
"fieldtype": "Float",
"hidden": 0,
@@ -1685,6 +1736,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "base_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1718,6 +1770,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "base_net_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1752,6 +1805,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_26",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1782,6 +1836,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1815,6 +1870,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "net_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1849,6 +1905,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "total_net_weight",
"fieldtype": "Float",
"hidden": 0,
@@ -1881,6 +1938,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "taxes_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1915,6 +1973,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
"fetch_if_empty": 0,
"fieldname": "taxes_and_charges",
"fieldtype": "Link",
"hidden": 0,
@@ -1949,6 +2008,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_50",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1980,6 +2040,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "shipping_rule",
"fieldtype": "Link",
"hidden": 0,
@@ -2013,6 +2074,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "section_break_52",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2044,6 +2106,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "taxes",
"fieldtype": "Table",
"hidden": 0,
@@ -2078,6 +2141,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "sec_tax_breakup",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2110,6 +2174,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "other_charges_calculation",
"fieldtype": "Text",
"hidden": 0,
@@ -2142,6 +2207,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "totals",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2175,6 +2241,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "base_taxes_and_charges_added",
"fieldtype": "Currency",
"hidden": 0,
@@ -2209,6 +2276,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "base_taxes_and_charges_deducted",
"fieldtype": "Currency",
"hidden": 0,
@@ -2243,6 +2311,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "base_total_taxes_and_charges",
"fieldtype": "Currency",
"hidden": 0,
@@ -2277,6 +2346,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_39",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2308,6 +2378,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "taxes_and_charges_added",
"fieldtype": "Currency",
"hidden": 0,
@@ -2342,6 +2413,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "taxes_and_charges_deducted",
"fieldtype": "Currency",
"hidden": 0,
@@ -2376,6 +2448,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "total_taxes_and_charges",
"fieldtype": "Currency",
"hidden": 0,
@@ -2410,6 +2483,7 @@
"collapsible": 1,
"collapsible_depends_on": "discount_amount",
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "discount_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2443,6 +2517,7 @@
"collapsible": 0,
"columns": 0,
"default": "Grand Total",
"fetch_if_empty": 0,
"fieldname": "apply_discount_on",
"fieldtype": "Select",
"hidden": 0,
@@ -2476,6 +2551,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "base_discount_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -2509,6 +2585,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_45",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2540,6 +2617,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "additional_discount_percentage",
"fieldtype": "Float",
"hidden": 0,
@@ -2572,6 +2650,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "discount_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -2605,6 +2684,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "totals_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2636,6 +2716,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "base_grand_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -2670,6 +2751,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "base_rounding_adjustment",
"fieldtype": "Currency",
"hidden": 0,
@@ -2704,6 +2786,7 @@
"collapsible": 0,
"columns": 0,
"description": "In Words will be visible once you save the Purchase Order.",
"fetch_if_empty": 0,
"fieldname": "base_in_words",
"fieldtype": "Data",
"hidden": 0,
@@ -2737,6 +2820,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "base_rounded_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -2771,6 +2855,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break4",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2802,6 +2887,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "grand_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -2836,6 +2922,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "rounding_adjustment",
"fieldtype": "Currency",
"hidden": 0,
@@ -2869,6 +2956,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "rounded_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -2881,6 +2969,7 @@
"label": "Rounded Total",
"length": 0,
"no_copy": 0,
"options": "currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -2901,6 +2990,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "disable_rounded_total",
"fieldtype": "Check",
"hidden": 0,
@@ -2933,6 +3023,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "in_words",
"fieldtype": "Data",
"hidden": 0,
@@ -2966,6 +3057,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "advance_paid",
"fieldtype": "Currency",
"hidden": 0,
@@ -2998,6 +3090,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "payment_schedule_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3030,6 +3123,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "payment_terms_template",
"fieldtype": "Link",
"hidden": 0,
@@ -3063,6 +3157,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "payment_schedule",
"fieldtype": "Table",
"hidden": 0,
@@ -3097,6 +3192,7 @@
"collapsible": 1,
"collapsible_depends_on": "terms",
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "terms_section_break",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3130,6 +3226,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "tc_name",
"fieldtype": "Link",
"hidden": 0,
@@ -3164,6 +3261,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "terms",
"fieldtype": "Text Editor",
"hidden": 0,
@@ -3197,6 +3295,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "more_info",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3230,6 +3329,7 @@
"collapsible": 0,
"columns": 0,
"default": "Draft",
"fetch_if_empty": 0,
"fieldname": "status",
"fieldtype": "Select",
"hidden": 0,
@@ -3264,6 +3364,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "ref_sq",
"fieldtype": "Data",
"hidden": 1,
@@ -3297,6 +3398,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "party_account_currency",
"fieldtype": "Link",
"hidden": 1,
@@ -3330,6 +3432,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_74",
"fieldtype": "Column Break",
"hidden": 0,
@@ -3363,6 +3466,7 @@
"columns": 0,
"depends_on": "eval:!doc.__islocal",
"description": "",
"fetch_if_empty": 0,
"fieldname": "per_received",
"fieldtype": "Percent",
"hidden": 0,
@@ -3398,6 +3502,7 @@
"columns": 0,
"depends_on": "eval:!doc.__islocal",
"description": "",
"fetch_if_empty": 0,
"fieldname": "per_billed",
"fieldtype": "Percent",
"hidden": 0,
@@ -3431,6 +3536,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break5",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3465,6 +3571,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "letter_head",
"fieldtype": "Link",
"hidden": 0,
@@ -3499,6 +3606,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "select_print_heading",
"fieldtype": "Link",
"hidden": 0,
@@ -3533,6 +3641,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_86",
"fieldtype": "Column Break",
"hidden": 0,
@@ -3565,6 +3674,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
"fetch_if_empty": 0,
"fieldname": "group_same_items",
"fieldtype": "Check",
"hidden": 0,
@@ -3598,6 +3708,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
"fetch_if_empty": 0,
"fieldname": "language",
"fieldtype": "Data",
"hidden": 0,
@@ -3631,6 +3742,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "subscription_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3665,6 +3777,7 @@
"columns": 0,
"depends_on": "",
"description": "",
"fetch_if_empty": 0,
"fieldname": "from_date",
"fieldtype": "Date",
"hidden": 0,
@@ -3698,6 +3811,7 @@
"columns": 0,
"depends_on": "",
"description": "",
"fetch_if_empty": 0,
"fieldname": "to_date",
"fieldtype": "Date",
"hidden": 0,
@@ -3729,6 +3843,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_97",
"fieldtype": "Column Break",
"hidden": 0,
@@ -3760,6 +3875,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "auto_repeat",
"fieldtype": "Link",
"hidden": 0,
@@ -3794,6 +3910,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval: doc.auto_repeat",
"fetch_if_empty": 0,
"fieldname": "update_auto_repeat_reference",
"fieldtype": "Button",
"hidden": 0,
@@ -3831,7 +3948,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2019-01-07 16:51:56.739693",
"modified": "2019-06-24 20:55:03.466766",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order",

View File

@@ -8,7 +8,9 @@ import frappe.defaults
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
from frappe.utils import flt, add_days, nowdate, getdate
from erpnext.stock.doctype.item.test_item import make_item
from erpnext.buying.doctype.purchase_order.purchase_order import (make_purchase_receipt, make_purchase_invoice, make_rm_stock_entry as make_subcontract_transfer_entry)
from erpnext.buying.doctype.purchase_order.purchase_order \
import (make_purchase_receipt, make_purchase_invoice as make_pi_from_po, make_rm_stock_entry as make_subcontract_transfer_entry)
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import make_purchase_invoice as make_pi_from_pr
from erpnext.stock.doctype.material_request.test_material_request import make_material_request
from erpnext.stock.doctype.material_request.material_request import make_purchase_order
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
@@ -62,7 +64,7 @@ class TestPurchaseOrder(unittest.TestCase):
frappe.db.set_value('Item', '_Test Item', 'tolerance', 50)
pi = make_purchase_invoice(po.name)
pi = make_pi_from_po(po.name)
pi.update_stock = 1
pi.items[0].qty = 12
pi.insert()
@@ -89,7 +91,7 @@ class TestPurchaseOrder(unittest.TestCase):
create_pr_against_po(po.name)
make_purchase_invoice(po.name)
make_pi_from_po(po.name)
existing_ordered_qty = get_ordered_qty()
existing_requested_qty = get_requested_qty()
@@ -108,14 +110,85 @@ class TestPurchaseOrder(unittest.TestCase):
self.assertEqual(po.get("items")[0].amount, 1400)
self.assertEqual(get_ordered_qty(), existing_ordered_qty + 3)
def test_update_qty(self):
po = create_purchase_order()
pr = make_pr_against_po(po.name, 2)
po.load_from_db()
self.assertEqual(po.get("items")[0].received_qty, 2)
# Check received_qty after making PI from PR without update_stock checked
pi1 = make_pi_from_pr(pr.name)
pi1.get("items")[0].qty = 2
pi1.insert()
pi1.submit()
po.load_from_db()
self.assertEqual(po.get("items")[0].received_qty, 2)
# Check received_qty after making PI from PO with update_stock checked
pi2 = make_pi_from_po(po.name)
pi2.set("update_stock", 1)
pi2.get("items")[0].qty = 3
pi2.insert()
pi2.submit()
po.load_from_db()
self.assertEqual(po.get("items")[0].received_qty, 5)
# Check received_qty after making PR from PO
pr = make_pr_against_po(po.name, 1)
po.load_from_db()
self.assertEqual(po.get("items")[0].received_qty, 6)
def test_return_against_purchase_order(self):
po = create_purchase_order()
pr = make_pr_against_po(po.name, 6)
po.load_from_db()
self.assertEqual(po.get("items")[0].received_qty, 6)
pi2 = make_pi_from_po(po.name)
pi2.set("update_stock", 1)
pi2.get("items")[0].qty = 3
pi2.insert()
pi2.submit()
po.load_from_db()
self.assertEqual(po.get("items")[0].received_qty, 9)
# Make return purchase receipt, purchase invoice and check quantity
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt \
import make_purchase_receipt as make_purchase_receipt_return
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice \
import make_purchase_invoice as make_purchase_invoice_return
pr1 = make_purchase_receipt_return(is_return=1, return_against=pr.name, qty=-3, do_not_submit=True)
pr1.items[0].purchase_order = po.name
pr1.items[0].purchase_order_item = po.items[0].name
pr1.submit()
pi1= make_purchase_invoice_return(is_return=1, return_against=pi2.name, qty=-1, update_stock=1, do_not_submit=True)
pi1.items[0].purchase_order = po.name
pi1.items[0].po_detail = po.items[0].name
pi1.submit()
po.load_from_db()
self.assertEqual(po.get("items")[0].received_qty, 5)
def test_make_purchase_invoice(self):
po = create_purchase_order(do_not_submit=True)
self.assertRaises(frappe.ValidationError, make_purchase_invoice, po.name)
self.assertRaises(frappe.ValidationError, make_pi_from_po, po.name)
po.submit()
pi = make_purchase_invoice(po.name)
pi = make_pi_from_po(po.name)
self.assertEqual(pi.doctype, "Purchase Invoice")
self.assertEqual(len(pi.get("items", [])), 1)
@@ -123,7 +196,7 @@ class TestPurchaseOrder(unittest.TestCase):
def test_make_purchase_invoice_with_terms(self):
po = create_purchase_order(do_not_save=True)
self.assertRaises(frappe.ValidationError, make_purchase_invoice, po.name)
self.assertRaises(frappe.ValidationError, make_pi_from_po, po.name)
po.update(
{"payment_terms_template": "_Test Payment Term Template"}
@@ -136,7 +209,7 @@ class TestPurchaseOrder(unittest.TestCase):
self.assertEqual(getdate(po.payment_schedule[0].due_date), getdate(po.transaction_date))
self.assertEqual(po.payment_schedule[1].payment_amount, 2500.0)
self.assertEqual(getdate(po.payment_schedule[1].due_date), add_days(getdate(po.transaction_date), 30))
pi = make_purchase_invoice(po.name)
pi = make_pi_from_po(po.name)
pi.save()
self.assertEqual(pi.doctype, "Purchase Invoice")
@@ -274,7 +347,7 @@ class TestPurchaseOrder(unittest.TestCase):
self.assertTrue(po.get('payment_schedule'))
pi = make_purchase_invoice(po.name)
pi = make_pi_from_po(po.name)
self.assertFalse(pi.get('payment_schedule'))
@@ -285,7 +358,7 @@ class TestPurchaseOrder(unittest.TestCase):
po.submit()
self.assertTrue(po.get('payment_schedule'))
pi = make_purchase_invoice(po.name)
pi = make_pi_from_po(po.name)
pi.insert()
self.assertTrue(pi.get('payment_schedule'))
@@ -365,7 +438,7 @@ class TestPurchaseOrder(unittest.TestCase):
self.assertEquals(bin7.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
# Make Purchase Invoice
pi = make_purchase_invoice(po.name)
pi = make_pi_from_po(po.name)
pi.update_stock = 1
pi.supplier_warehouse = "_Test Warehouse 1 - _TC"
pi.insert()
@@ -469,6 +542,13 @@ class TestPurchaseOrder(unittest.TestCase):
self.assertEquals(se_items, supplied_items)
update_backflush_based_on("BOM")
def make_pr_against_po(po, received_qty=0):
pr = make_purchase_receipt(po)
pr.get("items")[0].qty = received_qty or 5
pr.insert()
pr.submit()
return pr
def make_subcontracted_item(item_code):
from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom

View File

@@ -1915,7 +1915,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "1",
"default": "0",
"depends_on": "eval:parent.is_subcontracted == 'Yes'",
"fieldname": "include_exploded_items",
"fieldtype": "Check",
@@ -2344,7 +2344,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2019-01-07 16:51:57.546323",
"modified": "2019-06-23 20:03:13.818917",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order Item",
@@ -2359,4 +2359,4 @@
"track_changes": 1,
"track_seen": 0,
"track_views": 0
}
}

View File

@@ -199,7 +199,7 @@ def get_data():
"type": "report",
"is_query_report": True,
"name": "Address And Contacts",
"label": "Supplier Addresses And Contacts",
"label": _("Supplier Addresses And Contacts"),
"doctype": "Address",
"route_options": {
"party_type": "Supplier"

View File

@@ -291,6 +291,12 @@ def get_data():
"name": "Customers Without Any Sales Transactions",
"doctype": "Customer"
},
{
"type": "report",
"is_query_report": True,
"name": "Sales Partners Commission",
"doctype": "Customer"
}
]
},
{

View File

@@ -237,6 +237,10 @@ class AccountsController(TransactionBase):
document_type = "{} Item".format(self.doctype)
parent_dict.update({"document_type": document_type})
# party_name field used for customer in quotation
if self.doctype == "Quotation" and self.quotation_to == "Customer" and parent_dict.get("party_name"):
parent_dict.update({"customer": parent_dict.get("party_name")})
for item in self.get("items"):
if item.get("item_code"):
args = parent_dict.copy()
@@ -344,7 +348,7 @@ class AccountsController(TransactionBase):
'fiscal_year': fiscal_year,
'voucher_type': self.doctype,
'voucher_no': self.name,
'remarks': self.get("remarks"),
'remarks': self.get("remarks") or self.get("remark"),
'debit': 0,
'credit': 0,
'debit_in_account_currency': 0,
@@ -370,7 +374,7 @@ class AccountsController(TransactionBase):
def validate_qty_is_not_zero(self):
for item in self.items:
if not item.qty:
frappe.throw("Item quantity can not be zero")
frappe.throw(_("Item quantity can not be zero"))
def validate_account_currency(self, account, account_currency=None):
valid_currency = [self.company_currency]
@@ -743,7 +747,12 @@ class AccountsController(TransactionBase):
count += 1
item.qty = group_item_qty[item.item_code]
item.amount = group_item_amount[item.item_code]
item.rate = flt(flt(item.amount) / flt(item.qty), item.precision("rate"))
if item.qty:
item.rate = flt(flt(item.amount) / flt(item.qty), item.precision("rate"))
else:
item.rate = 0
item.idx = count
del group_item_qty[item.item_code]
else:
@@ -763,6 +772,9 @@ class AccountsController(TransactionBase):
if self.doctype in ("Sales Invoice", "Purchase Invoice"):
grand_total = grand_total - flt(self.write_off_amount)
if self.get("total_advance"):
grand_total -= self.get("total_advance")
if not self.get("payment_schedule"):
if self.get("payment_terms_template"):
data = get_payment_terms(self.payment_terms_template, posting_date, grand_total)
@@ -808,6 +820,9 @@ class AccountsController(TransactionBase):
total = flt(total, self.precision("grand_total"))
grand_total = flt(self.get("rounded_total") or self.grand_total, self.precision('grand_total'))
if self.get("total_advance"):
grand_total -= self.get("total_advance")
if self.doctype in ("Sales Invoice", "Purchase Invoice"):
grand_total = grand_total - flt(self.write_off_amount)
if total != grand_total:

View File

@@ -428,8 +428,9 @@ class BuyingController(StockController):
elif not flt(d.rejected_qty):
d.rejected_qty = flt(d.received_qty) - flt(d.qty)
val = flt(d.qty) + flt(d.rejected_qty)
# Check Received Qty = Accepted Qty + Rejected Qty
if ((flt(d.qty) + flt(d.rejected_qty)) != flt(d.received_qty)):
if (flt(val, d.precision("received_qty")) != flt(d.received_qty, d.precision("received_qty"))):
frappe.throw(_("Accepted + Rejected Qty must be equal to Received quantity for Item {0}").format(d.item_code))
def validate_negative_quantity(self, item_row, field_list):

View File

@@ -287,14 +287,14 @@ def copy_attributes_to_variant(item, variant):
variant.set(field.fieldname, item.get(field.fieldname))
variant.variant_of = item.name
if 'description' in allow_fields:
variant.has_variants = 0
if 'description' not in allow_fields:
if not variant.description:
variant.description = ""
variant.description = ""
if item.variant_based_on=='Item Attribute':
if variant.attributes:
attributes_description = ""
attributes_description = item.description + " "
for d in variant.attributes:
attributes_description += "<div>" + d.attribute + ": " + cstr(d.attribute_value) + "</div>"

View File

@@ -206,11 +206,11 @@ def bom(doctype, txt, searchfield, start, page_len, filters):
if(locate(%(_txt)s, name), locate(%(_txt)s, name), 99999),
idx desc, name
limit %(start)s, %(page_len)s """.format(
fcond=get_filters_cond(doctype, filters, conditions),
fcond=get_filters_cond(doctype, filters, conditions).replace('%', '%%'),
mcond=get_match_cond(doctype),
key=frappe.db.escape(searchfield)),
{
'txt': "%%%s%%" % frappe.db.escape(txt),
'txt': "%"+frappe.db.escape(txt)+"%",
'_txt': txt.replace("%", ""),
'start': start or 0,
'page_len': page_len or 20
@@ -254,11 +254,13 @@ def get_delivery_notes_to_be_billed(doctype, txt, searchfield, start, page_len,
and return_against in (select name from `tabDelivery Note` where per_billed < 100)
)
)
%(mcond)s order by `tabDelivery Note`.`%(key)s` asc
%(mcond)s order by `tabDelivery Note`.`%(key)s` asc limit %(start)s, %(page_len)s
""" % {
"key": searchfield,
"fcond": get_filters_cond(doctype, filters, []),
"mcond": get_match_cond(doctype),
"start": start,
"page_len": page_len,
"txt": "%(txt)s"
}, {"txt": ("%%%s%%" % txt)}, as_dict=as_dict)
@@ -295,7 +297,6 @@ def get_batch_no(doctype, txt, searchfield, start, page_len, filters):
order by batch.expiry_date, sle.batch_no desc
limit %(start)s, %(page_len)s""".format(cond, match_conditions=get_match_cond(doctype)), args)
if batch_nos:
return batch_nos
else:
return frappe.db.sql("""select name, concat('MFG-', manufacturing_date), concat('EXP-',expiry_date) from `tabBatch` batch

View File

@@ -75,7 +75,7 @@ def validate_returned_items(doc):
items_returned = False
for d in doc.get("items"):
if flt(d.qty) < 0 or d.get('received_qty') < 0:
if d.item_code and (flt(d.qty) < 0 or d.get('received_qty') < 0):
if d.item_code not in valid_items:
frappe.throw(_("Row # {0}: Returned Item {1} does not exists in {2} {3}")
.format(d.idx, d.item_code, doc.doctype, doc.return_against))
@@ -107,6 +107,9 @@ def validate_returned_items(doc):
items_returned = True
elif d.item_name:
items_returned = True
if not items_returned:
frappe.throw(_("Atleast one item should be entered with negative quantity in return document"))
@@ -205,11 +208,14 @@ def get_already_returned_items(doc):
def make_return_doc(doctype, source_name, target_doc=None):
from frappe.model.mapper import get_mapped_doc
company = frappe.db.get_value("Delivery Note", source_name, "company")
default_warehouse_for_sales_return = frappe.db.get_value("Company", company, "default_warehouse_for_sales_return")
def set_missing_values(source, target):
doc = frappe.get_doc(target)
doc.is_return = 1
doc.return_against = source.name
doc.ignore_pricing_rule = 1
doc.set_warehouse = ""
if doctype == "Sales Invoice":
doc.is_pos = source.is_pos
@@ -277,12 +283,16 @@ def make_return_doc(doctype, source_name, target_doc=None):
target_doc.so_detail = source_doc.so_detail
target_doc.si_detail = source_doc.si_detail
target_doc.expense_account = source_doc.expense_account
if default_warehouse_for_sales_return:
target_doc.warehouse = default_warehouse_for_sales_return
elif doctype == "Sales Invoice":
target_doc.sales_order = source_doc.sales_order
target_doc.delivery_note = source_doc.delivery_note
target_doc.so_detail = source_doc.so_detail
target_doc.dn_detail = source_doc.dn_detail
target_doc.expense_account = source_doc.expense_account
if default_warehouse_for_sales_return:
target_doc.warehouse = default_warehouse_for_sales_return
def update_terms(source_doc, target_doc, source_parent):
target_doc.payment_amount = -source_doc.payment_amount

View File

@@ -55,14 +55,28 @@ class SellingController(StockController):
self.set_price_list_and_item_details(for_validate=for_validate)
def set_missing_lead_customer_details(self):
customer, lead = None, None
if getattr(self, "customer", None):
customer = self.customer
elif self.doctype == "Opportunity" and self.party_name:
if self.opportunity_from == "Customer":
customer = self.party_name
else:
lead = self.party_name
elif self.doctype == "Quotation" and self.party_name:
if self.quotation_to == "Customer":
customer = self.party_name
else:
lead = self.party_name
if customer:
from erpnext.accounts.party import _get_party_details
fetch_payment_terms_template = False
if (self.get("__islocal") or
self.company != frappe.db.get_value(self.doctype, self.name, 'company')):
fetch_payment_terms_template = True
party_details = _get_party_details(self.customer,
party_details = _get_party_details(customer,
ignore_permissions=self.flags.ignore_permissions,
doctype=self.doctype, company=self.company,
fetch_payment_terms_template=fetch_payment_terms_template,
@@ -71,10 +85,9 @@ class SellingController(StockController):
party_details.pop("sales_team")
self.update_if_missing(party_details)
elif getattr(self, "lead", None):
elif lead:
from erpnext.crm.doctype.lead.lead import get_lead_details
self.update_if_missing(get_lead_details(
self.lead,
self.update_if_missing(get_lead_details(lead,
posting_date=self.get('transaction_date') or self.get('posting_date'),
company=self.company))

View File

@@ -27,15 +27,15 @@ status_map = {
],
"Quotation": [
["Draft", None],
["Submitted", "eval:self.docstatus==1"],
["Open", "eval:self.docstatus==1"],
["Lost", "eval:self.status=='Lost'"],
["Ordered", "has_sales_order"],
["Cancelled", "eval:self.docstatus==2"],
],
"Sales Order": [
["Draft", None],
["To Deliver and Bill", "eval:self.per_delivered < 100 and self.per_billed < 100 and self.docstatus == 1 and self.order_type in ['Sales', 'Shopping Cart']"],
["To Bill", "eval:self.per_delivered == 100 or self.order_type == 'Maintenance' and self.per_billed < 100 and self.docstatus == 1"],
["To Deliver and Bill", "eval:self.per_delivered < 100 and self.per_billed < 100 and self.docstatus == 1"],
["To Bill", "eval:self.per_delivered == 100 and self.per_billed < 100 and self.docstatus == 1"],
["To Deliver", "eval:self.per_delivered < 100 and self.per_billed == 100 and self.docstatus == 1"],
["Completed", "eval:self.per_delivered == 100 and self.per_billed == 100 and self.docstatus == 1"],
["Completed", "eval:self.order_type == 'Maintenance' and self.per_billed == 100 and self.docstatus == 1"],
@@ -45,9 +45,9 @@ status_map = {
"Sales Invoice": [
["Draft", None],
["Submitted", "eval:self.docstatus==1"],
["Paid", "eval:self.outstanding_amount==0 and self.docstatus==1"],
["Return", "eval:self.is_return==1 and self.docstatus==1"],
["Paid", "eval:self.outstanding_amount<=0 and self.docstatus==1 and self.is_return==0"],
["Credit Note Issued", "eval:self.outstanding_amount < 0 and self.docstatus==1 and self.is_return==0 and get_value('Sales Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1})"],
["Credit Note Issued", "eval:self.outstanding_amount < 0 and self.docstatus==1"],
["Unpaid", "eval:self.outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()) and self.docstatus==1"],
["Overdue", "eval:self.outstanding_amount > 0 and getdate(self.due_date) < getdate(nowdate()) and self.docstatus==1"],
["Cancelled", "eval:self.docstatus==2"],
@@ -55,9 +55,9 @@ status_map = {
"Purchase Invoice": [
["Draft", None],
["Submitted", "eval:self.docstatus==1"],
["Paid", "eval:self.outstanding_amount==0 and self.docstatus==1"],
["Return", "eval:self.is_return==1 and self.docstatus==1"],
["Paid", "eval:self.outstanding_amount<=0 and self.docstatus==1 and self.is_return==0"],
["Debit Note Issued", "eval:self.outstanding_amount < 0 and self.docstatus==1 and self.is_return==0 and get_value('Purchase Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1})"],
["Debit Note Issued", "eval:self.outstanding_amount < 0 and self.docstatus==1"],
["Unpaid", "eval:self.outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()) and self.docstatus==1"],
["Overdue", "eval:self.outstanding_amount > 0 and getdate(self.due_date) < getdate(nowdate()) and self.docstatus==1"],
["Cancelled", "eval:self.docstatus==2"],
@@ -316,19 +316,27 @@ class StatusUpdater(Document):
.format(frappe.db.escape(frappe.session.user))
def update_billing_status_for_zero_amount_refdoc(self, ref_dt):
ref_fieldname = ref_dt.lower().replace(" ", "_")
zero_amount_refdoc = []
all_zero_amount_refdoc = frappe.db.sql_list("""select name from `tab%s`
where docstatus=1 and base_net_total = 0""" % ref_dt)
ref_fieldname = frappe.scrub(ref_dt)
for item in self.get("items"):
if item.get(ref_fieldname) \
and item.get(ref_fieldname) in all_zero_amount_refdoc \
and item.get(ref_fieldname) not in zero_amount_refdoc:
zero_amount_refdoc.append(item.get(ref_fieldname))
ref_docs = [item.get(ref_fieldname) for item in (self.get('items') or []) if item.get(ref_fieldname)]
if not ref_docs:
return
if zero_amount_refdoc:
self.update_billing_status(zero_amount_refdoc, ref_dt, ref_fieldname)
zero_amount_refdocs = frappe.db.sql_list("""
SELECT
name
from
`tab{ref_dt}`
where
docstatus = 1
and base_net_total = 0
and name in %(ref_docs)s
""".format(ref_dt=ref_dt), {
'ref_docs': ref_docs
})
if zero_amount_refdocs:
self.update_billing_status(zero_amount_refdocs, ref_dt, ref_fieldname)
def update_billing_status(self, zero_amount_refdoc, ref_dt, ref_fieldname):
for ref_dn in zero_amount_refdoc:

View File

@@ -80,6 +80,7 @@ class StockController(AccountsController):
"cost_center": item_row.cost_center,
"remarks": self.get("remarks") or "Accounting Entry for Stock",
"debit": flt(sle.stock_value_difference, 2),
"is_opening": item_row.get("is_opening") or self.get("is_opening") or "No",
}, warehouse_account[sle.warehouse]["account_currency"]))
# to target warehouse / expense account
@@ -89,7 +90,8 @@ class StockController(AccountsController):
"cost_center": item_row.cost_center,
"remarks": self.get("remarks") or "Accounting Entry for Stock",
"credit": flt(sle.stock_value_difference, 2),
"project": item_row.get("project") or self.get("project")
"project": item_row.get("project") or self.get("project"),
"is_opening": item_row.get("is_opening") or self.get("is_opening") or "No"
}))
elif sle.warehouse not in warehouse_with_no_account:
warehouse_with_no_account.append(sle.warehouse)
@@ -123,8 +125,17 @@ class StockController(AccountsController):
def get_voucher_details(self, default_expense_account, default_cost_center, sle_map):
if self.doctype == "Stock Reconciliation":
return [frappe._dict({ "name": voucher_detail_no, "expense_account": default_expense_account,
"cost_center": default_cost_center }) for voucher_detail_no, sle in sle_map.items()]
reconciliation_purpose = frappe.db.get_value(self.doctype, self.name, "purpose")
is_opening = "Yes" if reconciliation_purpose == "Opening Stock" else "No"
details = []
for voucher_detail_no in sle_map:
details.append(frappe._dict({
"name": voucher_detail_no,
"expense_account": default_expense_account,
"cost_center": default_cost_center,
"is_opening": is_opening
}))
return details
else:
details = self.get("items")
@@ -351,10 +362,12 @@ class StockController(AccountsController):
frappe.throw(_("Row {0}: Quality Inspection rejected for item {1}")
.format(d.idx, d.item_code), QualityInspectionRejectedError)
elif qa_required :
frappe.msgprint(_("Quality Inspection required for Item {0}").format(d.item_code))
if self.docstatus==1:
raise QualityInspectionRequiredError
action = frappe.get_doc('Stock Settings').action_if_quality_inspection_is_not_submitted
if self.docstatus==1 and action == 'Stop':
frappe.throw(_("Quality Inspection required for Item {0} to submit").format(frappe.bold(d.item_code)),
exc=QualityInspectionRequiredError)
else:
frappe.msgprint(_("Create Quality Inspection for Item {0}").format(frappe.bold(d.item_code)))
def update_blanket_order(self):
blanket_orders = list(set([d.blanket_order for d in self.items if d.blanket_order]))

View File

@@ -390,7 +390,7 @@ class calculate_taxes_and_totals(object):
net_total += item.net_amount
# discount amount rounding loss adjustment if no taxes
if (not taxes or self.doc.apply_discount_on == "Net Total") \
if (self.doc.apply_discount_on == "Net Total" or not taxes or total_for_discount_amount==self.doc.net_total) \
and i == len(self.doc.get("items")) - 1:
discount_amount_loss = flt(self.doc.net_total - net_total - self.doc.discount_amount,
self.doc.precision("net_total"))
@@ -608,7 +608,7 @@ def get_itemised_tax_breakup_data(doc):
return itemised_tax, itemised_taxable_amount
def get_itemised_tax(taxes):
def get_itemised_tax(taxes, with_tax_account=False):
itemised_tax = {}
for tax in taxes:
if getattr(tax, "category", None) and tax.category=="Valuation":
@@ -633,6 +633,9 @@ def get_itemised_tax(taxes):
tax_amount = tax_amount
))
if with_tax_account:
itemised_tax[item_code][tax.description].tax_account = tax.account_head
return itemised_tax
def get_itemised_taxable_amount(items):

View File

@@ -43,7 +43,7 @@ class TestMapper(unittest.TestCase):
qtn = frappe.get_doc({
"doctype": "Quotation",
"quotation_to": "Customer",
"customer": customer,
"party_name": customer,
"order_type": "Sales",
"transaction_date" : nowdate(),
"valid_till" : add_months(nowdate(), 1)

View File

@@ -5,79 +5,91 @@ frappe.provide("erpnext");
cur_frm.email_field = "email_id";
erpnext.LeadController = frappe.ui.form.Controller.extend({
setup: function() {
this.frm.fields_dict.customer.get_query = function(doc, cdt, cdn) {
return { query: "erpnext.controllers.queries.customer_query" } }
setup: function () {
this.frm.make_methods = {
'Quotation': () => erpnext.utils.create_new_doc('Quotation', {
'quotation_to': this.frm.doc.doctype,
'party_name': this.frm.doc.name
}),
'Opportunity': () => erpnext.utils.create_new_doc('Opportunity', {
'opportunity_from': this.frm.doc.doctype,
'party_name': this.frm.doc.name
})
}
this.frm.fields_dict.customer.get_query = function (doc, cdt, cdn) {
return { query: "erpnext.controllers.queries.customer_query" }
}
this.frm.toggle_reqd("lead_name", !this.frm.doc.organization_lead);
},
onload: function() {
if(cur_frm.fields_dict.lead_owner.df.options.match(/^User/)) {
cur_frm.fields_dict.lead_owner.get_query = function(doc, cdt, cdn) {
onload: function () {
if (cur_frm.fields_dict.lead_owner.df.options.match(/^User/)) {
cur_frm.fields_dict.lead_owner.get_query = function (doc, cdt, cdn) {
return { query: "frappe.core.doctype.user.user.user_query" }
}
}
if(cur_frm.fields_dict.contact_by.df.options.match(/^User/)) {
cur_frm.fields_dict.contact_by.get_query = function(doc, cdt, cdn) {
return { query: "frappe.core.doctype.user.user.user_query" } }
if (cur_frm.fields_dict.contact_by.df.options.match(/^User/)) {
cur_frm.fields_dict.contact_by.get_query = function (doc, cdt, cdn) {
return { query: "frappe.core.doctype.user.user.user_query" }
}
}
},
refresh: function() {
refresh: function () {
var doc = this.frm.doc;
erpnext.toggle_naming_series();
frappe.dynamic_link = {doc: doc, fieldname: 'name', doctype: 'Lead'}
frappe.dynamic_link = { doc: doc, fieldname: 'name', doctype: 'Lead' }
if(!doc.__islocal && doc.__onload && !doc.__onload.is_customer) {
if (!doc.__islocal && doc.__onload && !doc.__onload.is_customer) {
this.frm.add_custom_button(__("Customer"), this.create_customer, __("Make"));
this.frm.add_custom_button(__("Opportunity"), this.create_opportunity, __("Make"));
this.frm.add_custom_button(__("Quotation"), this.make_quotation, __("Make"));
}
if(!this.frm.doc.__islocal) {
if (!this.frm.doc.__islocal) {
frappe.contacts.render_address_and_contact(cur_frm);
} else {
frappe.contacts.clear_address_and_contact(cur_frm);
}
},
create_customer: function() {
create_customer: function () {
frappe.model.open_mapped_doc({
method: "erpnext.crm.doctype.lead.lead.make_customer",
frm: cur_frm
})
},
create_opportunity: function() {
create_opportunity: function () {
frappe.model.open_mapped_doc({
method: "erpnext.crm.doctype.lead.lead.make_opportunity",
frm: cur_frm
})
},
make_quotation: function() {
make_quotation: function () {
frappe.model.open_mapped_doc({
method: "erpnext.crm.doctype.lead.lead.make_quotation",
frm: cur_frm
})
},
organization_lead: function() {
if (this.frm.doc.organization_lead == 1) {
this.frm.set_df_property('company_name', 'reqd', 1);
} else {
this.frm.set_df_property('company_name', 'reqd', 0);
}
organization_lead: function () {
this.frm.toggle_reqd("lead_name", !this.frm.doc.organization_lead);
this.frm.toggle_reqd("company_name", this.frm.doc.organization_lead);
},
company_name: function() {
company_name: function () {
if (this.frm.doc.organization_lead == 1) {
this.frm.set_value("lead_name", this.frm.doc.company_name);
}
},
contact_date: function() {
contact_date: function () {
if (this.frm.doc.contact_date) {
let d = moment(this.frm.doc.contact_date);
d.add(1, "hours");
@@ -86,4 +98,4 @@ erpnext.LeadController = frappe.ui.form.Controller.extend({
}
});
$.extend(cur_frm.cscript, new erpnext.LeadController({frm: cur_frm}));
$.extend(cur_frm.cscript, new erpnext.LeadController({ frm: cur_frm }));

View File

@@ -141,7 +141,7 @@
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
"translatable": 0,
@@ -499,7 +499,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Lead Owner",
"length": 0,
@@ -1389,7 +1389,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-10-02 09:12:23.415379",
"modified": "2019-05-10 03:22:57.283628",
"modified_by": "Administrator",
"module": "CRM",
"name": "Lead",

View File

@@ -102,14 +102,18 @@ class Lead(SellingController):
def has_lost_quotation(self):
return frappe.db.get_value("Quotation", {
"lead": self.name,
"party_name": self.name,
"docstatus": 1,
"status": "Lost"
})
def set_lead_name(self):
if not self.lead_name:
frappe.db.set_value("Lead", self.name, "lead_name", self.company_name)
# Check for leads being created through data import
if not self.company_name and not self.flags.ignore_mandatory:
frappe.throw(_("A Lead requires either a person's name or an organization's name"))
self.lead_name = self.company_name
@frappe.whitelist()
def make_customer(source_name, target_doc=None):
@@ -146,8 +150,8 @@ def make_opportunity(source_name, target_doc=None):
"doctype": "Opportunity",
"field_map": {
"campaign_name": "campaign",
"doctype": "enquiry_from",
"name": "lead",
"doctype": "opportunity_from",
"name": "party_name",
"lead_name": "contact_display",
"company_name": "customer_name",
"email_id": "contact_email",
@@ -163,7 +167,7 @@ def make_quotation(source_name, target_doc=None):
{"Lead": {
"doctype": "Quotation",
"field_map": {
"name": "lead"
"name": "party_name"
}
}}, target_doc)
target_doc.quotation_to = "Lead"
@@ -225,4 +229,4 @@ def make_lead_from_communication(communication, ignore_communication_links=False
lead_name = lead.name
link_communication_to_document(doc, "Lead", lead_name, ignore_communication_links)
return lead_name
return lead_name

View File

@@ -4,6 +4,13 @@ from frappe import _
def get_data():
return {
'fieldname': 'lead',
'non_standard_fieldnames': {
'Quotation': 'party_name',
'Opportunity': 'party_name'
},
'dynamic_links': {
'party_name': ['Lead', 'quotation_to']
},
'transactions': [
{
'items': ['Opportunity', 'Quotation']

View File

@@ -20,10 +20,22 @@ frappe.ui.form.on("Opportunity", {
});
},
onload_post_render: function(frm) {
frm.get_field("items").grid.set_multiple_add("item_code", "qty");
},
party_name: function(frm) {
frm.toggle_display("contact_info", frm.doc.party_name);
if (frm.doc.opportunity_from == "Customer") {
frm.trigger('set_contact_link');
erpnext.utils.get_party_details(frm);
} else if (frm.doc.opportunity_from == "Lead") {
erpnext.utils.map_current_doc({
method: "erpnext.crm.doctype.lead.lead.make_opportunity",
source_name: frm.doc.party_name,
frm: frm
});
}
},
@@ -82,9 +94,9 @@ frappe.ui.form.on("Opportunity", {
set_contact_link: function(frm) {
if(frm.doc.opportunity_from == "Customer" && frm.doc.party_name) {
frappe.dynamic_link = {doc: frm.doc, fieldname: 'customer', doctype: 'Customer'}
frappe.dynamic_link = {doc: frm.doc, fieldname: 'party_name', doctype: 'Customer'}
} else if(frm.doc.opportunity_from == "Lead" && frm.doc.party_name) {
frappe.dynamic_link = {doc: frm.doc, fieldname: 'lead', doctype: 'Lead'}
frappe.dynamic_link = {doc: frm.doc, fieldname: 'party_name', doctype: 'Lead'}
}
},
@@ -138,12 +150,14 @@ erpnext.crm.Opportunity = frappe.ui.form.Controller.extend({
};
});
$.each([["lead", "lead"],
["customer", "customer"],
["contact_person", "contact_query"]],
function(i, opts) {
me.frm.set_query(opts[0], erpnext.queries[opts[1]]);
});
me.frm.set_query('contact_person', erpnext.queries['contact_query'])
if (me.frm.doc.opportunity_from == "Lead") {
me.frm.set_query('party_name', erpnext.queries['lead']);
}
else if (me.frm.doc.opportunity_from == "Cuatomer") {
me.frm.set_query('party_name', erpnext.queries['customer']);
}
},
create_quotation: function() {
@@ -156,11 +170,6 @@ erpnext.crm.Opportunity = frappe.ui.form.Controller.extend({
$.extend(cur_frm.cscript, new erpnext.crm.Opportunity({frm: cur_frm}));
cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) {
if(doc.opportunity_from == 'Lead' && doc.party_name)
cur_frm.cscript.lead(doc, cdt, cdn);
}
cur_frm.cscript.item_code = function(doc, cdt, cdn) {
var d = locals[cdt][cdn];
if (d.item_code) {
@@ -179,15 +188,6 @@ cur_frm.cscript.item_code = function(doc, cdt, cdn) {
}
}
cur_frm.cscript.lead = function(doc, cdt, cdn) {
cur_frm.toggle_display("contact_info", doc.party_name);
erpnext.utils.map_current_doc({
method: "erpnext.crm.doctype.lead.lead.make_opportunity",
source_name: cur_frm.doc.party_name,
frm: cur_frm
});
}
cur_frm.cscript['Declare Opportunity Lost'] = function() {
var dialog = new frappe.ui.Dialog({
title: __("Set as Lost"),

View File

@@ -99,7 +99,7 @@
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"in_standard_filter": 1,
"label": "Opportunity From",
"length": 0,
"no_copy": 0,
@@ -136,7 +136,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Customer/Lead",
"label": "Party",
"length": 0,
"no_copy": 0,
"oldfieldname": "customer",
@@ -878,7 +878,7 @@
"collapsible": 1,
"collapsible_depends_on": "next_contact_by",
"columns": 0,
"depends_on": "eval:doc.lead || doc.customer",
"depends_on": "eval:doc.party_name",
"fetch_if_empty": 0,
"fieldname": "contact_info",
"fieldtype": "Section Break",
@@ -912,7 +912,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.customer || doc.lead",
"depends_on": "eval:doc.party_name",
"fetch_if_empty": 0,
"fieldname": "customer_address",
"fieldtype": "Link",
@@ -1083,7 +1083,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.lead || doc.customer",
"depends_on": "eval:doc.party_name",
"fetch_if_empty": 0,
"fieldname": "contact_person",
"fieldtype": "Link",
@@ -1150,7 +1150,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.lead || doc.customer",
"depends_on": "eval:doc.party_name",
"fetch_if_empty": 0,
"fieldname": "contact_email",
"fieldtype": "Data",
@@ -1183,7 +1183,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.lead || doc.customer",
"depends_on": "eval:doc.party_name",
"fetch_if_empty": 0,
"fieldname": "contact_mobile",
"fieldtype": "Small Text",
@@ -1468,7 +1468,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2019-04-25 18:55:43.874656",
"modified": "2019-05-17 19:03:32.740910",
"modified_by": "Administrator",
"module": "CRM",
"name": "Opportunity",

View File

@@ -320,11 +320,11 @@ def make_opportunity_from_communication(communication, ignore_communication_link
if not lead:
lead = make_lead_from_communication(communication, ignore_communication_links=True)
enquiry_from = "Lead"
opportunity_from = "Lead"
opportunity = frappe.get_doc({
"doctype": "Opportunity",
"enquiry_from": enquiry_from,
"opportunity_from": opportunity_from,
"lead": lead
}).insert(ignore_permissions=True)

View File

@@ -17,5 +17,13 @@ frappe.listview_settings['Opportunity'] = {
listview.page.add_menu_item(__("Set as Closed"), function() {
listview.call_for_selected_items(method, {"status": "Closed"});
});
listview.page.fields_dict.opportunity_from.get_query = function() {
return {
"filters": {
"name": ["in", ["Customer", "Lead"]],
}
};
};
}
};

View File

@@ -11,7 +11,7 @@ def execute(filters=None):
columns=get_columns("Campaign Name")
data=get_lead_data(filters or {}, "Campaign Name")
return columns, data
def get_columns(based_on):
return [
{
@@ -69,21 +69,21 @@ def get_columns(based_on):
"width": 100
}
]
def get_lead_data(filters, based_on):
based_on_field = frappe.scrub(based_on)
conditions = get_filter_conditions(filters)
lead_details = frappe.db.sql("""
select {based_on_field}, name
from `tabLead`
where {based_on_field} is not null and {based_on_field} != '' {conditions}
from `tabLead`
where {based_on_field} is not null and {based_on_field} != '' {conditions}
""".format(based_on_field=based_on_field, conditions=conditions), filters, as_dict=1)
lead_map = frappe._dict()
for d in lead_details:
lead_map.setdefault(d.get(based_on_field), []).append(d.name)
data = []
for based_on_value, leads in lead_map.items():
row = {
@@ -94,42 +94,42 @@ def get_lead_data(filters, based_on):
row["opp_count"] = get_lead_opp_count(leads)
row["order_count"] = get_quotation_ordered_count(leads)
row["order_value"] = get_order_amount(leads) or 0
row["opp_lead"] = flt(row["opp_count"]) / flt(row["lead_count"] or 1.0) * 100.0
row["quot_lead"] = flt(row["quot_count"]) / flt(row["lead_count"] or 1.0) * 100.0
row["order_quot"] = flt(row["order_count"]) / flt(row["quot_count"] or 1.0) * 100.0
data.append(row)
return data
def get_filter_conditions(filters):
conditions=""
if filters.from_date:
conditions += " and date(creation) >= %(from_date)s"
if filters.to_date:
conditions += " and date(creation) <= %(to_date)s"
return conditions
def get_lead_quotation_count(leads):
return frappe.db.sql("""select count(name) from `tabQuotation`
where lead in (%s)""" % ', '.join(["%s"]*len(leads)), tuple(leads))[0][0]
return frappe.db.sql("""select count(name) from `tabQuotation`
where quotation_to = 'Lead' and party_name in (%s)""" % ', '.join(["%s"]*len(leads)), tuple(leads))[0][0] #nosec
def get_lead_opp_count(leads):
return frappe.db.sql("""select count(name) from `tabOpportunity`
where lead in (%s)""" % ', '.join(["%s"]*len(leads)), tuple(leads))[0][0]
return frappe.db.sql("""select count(name) from `tabOpportunity`
where opportunity_from = 'Lead' and party_name in (%s)""" % ', '.join(["%s"]*len(leads)), tuple(leads))[0][0]
def get_quotation_ordered_count(leads):
return frappe.db.sql("""select count(name)
from `tabQuotation` where status = 'Ordered'
and lead in (%s)""" % ', '.join(["%s"]*len(leads)), tuple(leads))[0][0]
return frappe.db.sql("""select count(name)
from `tabQuotation` where status = 'Ordered' and quotation_to = 'Lead'
and party_name in (%s)""" % ', '.join(["%s"]*len(leads)), tuple(leads))[0][0]
def get_order_amount(leads):
return frappe.db.sql("""select sum(base_net_amount)
return frappe.db.sql("""select sum(base_net_amount)
from `tabSales Order Item`
where prevdoc_docname in (
select name from `tabQuotation` where status = 'Ordered'
and lead in (%s)
select name from `tabQuotation` where status = 'Ordered'
and quotation_to = 'Lead' and party_name in (%s)
)""" % ', '.join(["%s"]*len(leads)), tuple(leads))[0][0]

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