Compare commits

..

392 Commits

Author SHA1 Message Date
Ameya Shenoy
3f32218bc0 Merge branch 'hotfix' 2018-10-31 13:35:59 +00:00
Ameya Shenoy
b4bff7e298 bumped to version 10.1.66 2018-10-31 13:35:58 +00:00
Shreya Shah
41c5fda196 fix(sms-center): Fix db query (#15774) 2018-10-31 18:04:30 +05:30
Shreya Shah
305c82bd8d fix(medical-record): Remove z-index property (#15790) 2018-10-31 18:02:55 +05:30
rohitwaghchaure
cd11bdfdbb [Fix] Supplier wise sales analytics report not showing item details which is added in purchase invoice with update stock (#15869) 2018-10-31 18:02:00 +05:30
Shreya Shah
0c0e49a421 fix: Fix fieldnames in template (#15860) 2018-10-31 18:00:09 +05:30
rohitwaghchaure
3f398d24f3 [Fix] Precision issue, not able to submit the stock entry (#15863) 2018-10-31 17:58:26 +05:30
Ameya Shenoy
d9a82738d0 Merge branch 'hotfix' 2018-10-30 12:48:42 +00:00
Ameya Shenoy
1f7a5dcd07 bumped to version 10.1.65 2018-10-30 12:48:42 +00:00
Shreya Shah
452619c668 fix(report): Return if not list (#15849) 2018-10-30 11:26:01 +05:30
rohitwaghchaure
9d0dba5569 Merge pull request #15851 from frappe/pos-delete-fix
fix: Delete button in POS mobile
2018-10-29 15:19:11 +05:30
Faris Ansari
3df1327b94 fix: Delete button in POS mobile
Delete button was covered by page-actions container
2018-10-29 15:15:10 +05:30
Ameya Shenoy
38eaaade89 Merge branch 'hotfix' 2018-10-23 12:52:46 +00:00
Ameya Shenoy
2a98e59bd4 bumped to version 10.1.64 2018-10-23 12:52:46 +00:00
Ameya Shenoy
03348364e9 Merge pull request #15739 from kennethsequeira/hotfix
Fix for "Improve this page" incorrect link generated in v10 sites
2018-10-23 18:05:25 +05:30
Ameya Shenoy
83fd31973f Merge branch 'hotfix' 2018-10-23 07:58:12 +00:00
Ameya Shenoy
ac64b39562 bumped to version 10.1.63 2018-10-23 07:58:11 +00:00
Ameya Shenoy
c73c576536 Merge pull request #15759 from codingCoffee/salesperson
fix(): fetch correct warehouse for item in report
2018-10-23 13:25:42 +05:30
rohitwaghchaure
034429b34d Merge pull request #15756 from rohitwaghchaure/fixed_allow_edit_rate
[Fix] User able to edit the rate in offline POS even if it has no permissions
2018-10-23 09:43:57 +05:30
Ameya Shenoy
874866e9f9 Merge branch 'hotfix' 2018-10-22 10:34:35 +00:00
Ameya Shenoy
c365ce8f21 bumped to version 10.1.62 2018-10-22 10:34:35 +00:00
Ameya Shenoy
3a11f34355 fix(): fetch correct warehouse for item in report
Fix 'Sales Person-wise Transaction Summary' Report by fetching the
correct Warehouse for the Item fron the respective, Sales Order/Sales
Invoice/ Delivery Note
2018-10-22 10:15:07 +00:00
Nabin Hait
91eac5a7cf fix(report): Optimization for financial statements 2018-10-22 15:05:40 +05:30
Rohit Waghchaure
aef7a6ec44 [Fix] User able to edit the rate in offline POS even if it has no permissions 2018-10-22 13:51:32 +05:30
Ameya Shenoy
6192d24235 Merge branch 'hotfix' 2018-10-19 12:48:17 +00:00
Ameya Shenoy
24fe7286fc bumped to version 10.1.61 2018-10-19 12:48:16 +00:00
Kenneth Sequeira
991c121b57 added source link for ERPNext docs 2018-10-19 14:31:21 +05:30
Kenneth Sequeira
23ec18e3e4 added docs_app variable to point docs to foundation app 2018-10-19 03:28:12 +05:30
Nabin Hait
500ddc94c7 fix(gle): GL Entry for invoices before introduction of rounding_adjustment (#15732) 2018-10-18 16:48:28 +05:30
Ameya Shenoy
bbd8b04012 Merge branch 'hotfix' 2018-10-17 09:04:11 +00:00
Ameya Shenoy
bb1b6b42e2 bumped to version 10.1.60 2018-10-17 09:04:11 +00:00
Shreya Shah
8e71074e1c fix(report): Add column for Item Name (#15702) 2018-10-16 14:36:49 +05:30
Shreya Shah
ff0deedca9 fix(discount-amount): Print hide discount_amount if print without amount (#15704) 2018-10-16 14:34:30 +05:30
deepeshgarg007
4bb90add1d Currency symbol bug fix (#15698) 2018-10-15 19:07:49 +05:30
Nabin Hait
44ec05f79b fix(bom): deadlock issue via bom replace tool (#15694) 2018-10-15 18:56:16 +05:30
Bibin
7844b79274 [Bug-Fix] accounts_receivable.html (#15688)
* Update accounts_receivable.html

In the print format and PDF the total was showing as 0 (Zero) , when I made these changes it fixed the issue

* Update accounts_receivable.html
2018-10-15 18:25:26 +05:30
Nabin Hait
ea75295bb3 Merge branch 'hotfix' 2018-10-15 15:41:25 +05:30
Nabin Hait
d2c643eb0b bumped to version 10.1.59 2018-10-15 16:11:25 +06:00
rohitwaghchaure
94fcb0e9f9 [Enhance] Add user image in the employee from the user (#15680) 2018-10-15 14:57:46 +05:30
rohitwaghchaure
3362d6b948 [Fix] Precision issue in the expense claim (#15678) 2018-10-15 11:07:13 +05:30
Saurabh
75c1682e61 Merge branch 'hotfix' 2018-10-09 17:55:32 +05:30
Saurabh
2dc8972794 bumped to version 10.1.58 2018-10-09 18:25:32 +06:00
Saurabh
f786eccdf9 Merge pull request #15633 from Zlash65/setup-fix
[Minor] Setup Wizard failing fix
2018-10-09 17:49:54 +05:30
Zlash65
a1036ad50b setup wizard failing fix 2018-10-09 17:38:28 +05:30
Shreya Shah
5b34d00bc0 fix(accounts-receivable): Column values in Print and PDF (#15622) 2018-10-08 18:20:51 +05:30
Ameya Shenoy
ee3b788024 Merge branch 'hotfix' 2018-10-08 09:37:37 +00:00
Ameya Shenoy
b509b06edf bumped to version 10.1.57 2018-10-08 09:37:37 +00:00
Zarrar
5fcccda883 [Minor] Supplier Quotation (#15578)
* throw meaningful error if RFQ does not have selected supplier

* Update supplier_quotation.py

* codacy fix
2018-10-08 14:30:53 +05:30
Shreya Shah
4fb9230d16 Add missing method link_to_mrs to buying.js (#15613) 2018-10-08 14:18:03 +05:30
Shreya Shah
37d3686372 fix(setup_taxes): Pop if frappe.message_log (#15615) 2018-10-08 14:17:16 +05:30
Ameya Shenoy
5eafa5a487 Merge branch 'hotfix' 2018-10-05 08:54:46 +00:00
Ameya Shenoy
97dbb4d125 bumped to version 10.1.56 2018-10-05 08:54:46 +00:00
Shreya Shah
17ac38ff29 Enable save before saving to update form after save (#15579) 2018-10-05 11:51:13 +05:30
Ameya Shenoy
65652071ff Merge branch 'hotfix' 2018-10-04 09:11:50 +00:00
Ameya Shenoy
79dc8ac9cc bumped to version 10.1.55 2018-10-04 09:11:50 +00:00
rohitwaghchaure
15e7646edd Merge pull request #15569 from rohitwaghchaure/stock_adjustment_to_cost_of_goods_sold
Book cost of goods sold instead of stock adjustment
2018-10-03 17:36:29 +05:30
Rohit Waghchaure
d1b87ba41c Book cost of goods sold instead of stock adjustment 2018-10-03 16:29:43 +05:30
rohitwaghchaure
a5576f5b21 [Fix] Stock difference between gl entry and stock ledger entry booked in stock adjustment (#15374) 2018-10-03 10:39:50 +05:30
rohitwaghchaure
8976ad5ca1 Merge pull request #15523 from rohitwaghchaure/fix_attendance_tool_issue
[Fix] Attendance tool
2018-10-01 15:07:49 +05:30
Rohit Waghchaure
c7f8b82fff [Fix] Attendance tool 2018-10-01 12:30:58 +05:30
rohitwaghchaure
6b62b86bbf Merge pull request #15545 from rohitwaghchaure/salary_slip_not_creating_because_of_the_date_issue
[Fix] Salary slip
2018-10-01 12:03:26 +05:30
Rohit Waghchaure
8fbf856618 [Fix] Salary slip 2018-10-01 12:00:45 +05:30
Nabin Hait
7d6d678e8d purchase receipt return entry in dashboard 2018-09-26 19:04:11 +05:30
Nabin Hait
c22ba2ec26 fix(sales return): validation message fix 2018-09-26 18:56:45 +05:30
rohitwaghchaure
0cf0ebf08b [Refactored] Asset Depreciation Ledger report based on GL entries (#15415)
* [Refactored] Asset Depreciation Ledger report is based on GL entries

* Provision to make manual JV from the asset if Calculate Depreciation is disabled
2018-09-26 15:24:49 +05:30
Ameya Shenoy
0ff35a852a Merge branch 'hotfix' 2018-09-26 07:26:49 +00:00
Ameya Shenoy
e04431ea5c bumped to version 10.1.54 2018-09-26 07:26:49 +00:00
rohitwaghchaure
fafc277666 [Fix] BOM update tool, too many writes in one request. Please send smaller requests (#15432) 2018-09-25 18:59:20 +05:30
rohitwaghchaure
fe1e4a41e6 Validate negative stock serial number (#15492) 2018-09-25 18:36:32 +05:30
Faris Ansari
7a8c5b0c2c fix(setup wizard): Validate FY dates (#15473) 2018-09-25 18:34:33 +05:30
Saurabh
056ecdca6a Merge branch 'hotfix' 2018-09-20 13:22:36 +05:30
Saurabh
3b281a0a1b bumped to version 10.1.53 2018-09-20 13:52:36 +06:00
rohitwaghchaure
a60ab1af75 [Fix] Salary slip is not saving (#15449) 2018-09-20 13:18:49 +05:30
rohitwaghchaure
550fc695f1 [Fix] Precision issue in the accounts receivable report (#15440) 2018-09-19 19:03:40 +05:30
Zarrar
013493de7a lable for discount_amount should be configurable (#15408) 2018-09-17 11:06:49 +05:30
Saurabh
b3737c812a Merge branch 'hotfix' 2018-09-12 14:44:25 +05:30
Saurabh
6d5a29af6a bumped to version 10.1.52 2018-09-12 15:14:25 +06:00
Ahmed Madi
20d8c52d2a Update salary_slip.js (#15200) 2018-09-12 11:02:57 +05:30
Nabin Hait
e11f299b21 Update production_order.py 2018-09-11 11:36:05 +05:30
Zarrar
68000c66fc check if Data Migration Plan exists before deleting (#15368) 2018-09-09 19:19:13 +05:30
rohitwaghchaure
3cc77b52e7 [Fix] Timeout error for bom update tool (#15343) 2018-09-07 16:16:58 +05:30
rohitwaghchaure
bd4348db10 [Enhance] Add additional cost of the manufacture stock entry in the project costing (#15341) 2018-09-07 16:16:23 +05:30
Nabin Hait
4fd1cebf95 fix(patch): Delete all documents from Hub Node module 2018-09-06 18:53:46 +05:30
Faris Ansari
b892cc8b02 fix(item): Remove Hub Category field (#15331) 2018-09-06 18:02:48 +05:30
Nabin Hait
8652bce9e3 Update modules.txt 2018-09-06 14:18:49 +05:30
Faris Ansari
4e372a30fa fix(patch): Remove old Hub Page (#15328) 2018-09-06 14:08:31 +05:30
Prateeksha Singh
df327f2974 [remove-hub] delete hub module 2018-09-06 13:34:47 +05:30
Prateeksha Singh
3ccbb8f8b7 [remove-hub] delete hub_settings and hub_category 2018-09-06 13:28:47 +05:30
Zarrar
0d931e1d7d fix uom & stock_uom print hide logic (#15327) 2018-09-06 13:08:58 +05:30
johnhkelley1
431b4fba72 Allow for 0 valuation rate in Stock Reconciliation (#15313)
Currently, a valuation rate of 0 gets treated the same as an omitted
valuation rate, and gets overwritten during validation. This hotfix
allows a Stock Reconciliation Item's valuation rate to be set to 0.
2018-09-05 11:43:28 +05:30
Saurabh
fba985d49d Merge branch 'hotfix' 2018-09-03 17:00:15 +05:30
Saurabh
4bd562d669 bumped to version 10.1.51 2018-09-03 17:30:15 +06:00
Shreya Shah
bb88e964a4 Remove unnecessary code (#15296) 2018-09-03 13:01:12 +05:30
rohitwaghchaure
5f79479bd0 Merge pull request #15282 from rohitwaghchaure/budget_should_check_on_submit_document
[Minor] Don't validate on cancelled budgets
2018-08-31 16:59:56 +05:30
Rohit Waghchaure
12b4096e68 [Minor] Don't validate on cancelled budgest 2018-08-31 16:54:59 +05:30
Saurabh
1ef72c0b66 Merge branch 'hotfix' 2018-08-31 11:29:13 +05:30
Saurabh
648191b9e8 bumped to version 10.1.50 2018-08-31 11:59:13 +06:00
rohitwaghchaure
624927bf0b [Fix] Not able to export the Supplier-Wise Sales Analytics report (#15271) 2018-08-30 19:19:14 +05:30
Shreya Shah
3df2639a32 Optimize patch (#15263) 2018-08-30 17:24:03 +05:30
Nabin Hait
d982e8fcda Merge branch 'hotfix' 2018-08-29 13:13:54 +05:30
Nabin Hait
af497ef669 bumped to version 10.1.49 2018-08-29 13:43:53 +06:00
Saurabh
79f3ea4094 [minor][fix] call update_percent_complete via validate (#15235) 2018-08-28 14:01:34 +05:30
Shreya Shah
e0a47aeb2f Improve performance for warehouse tree (#15207)
* Fix conflicts

* Modify query structure

* Remove whitespaces
2018-08-28 13:46:22 +05:30
Ahmed Madi
1516b8d54a Update asset_category.js (#15222) 2018-08-27 12:04:12 +05:30
rohitwaghchaure
e33047250e [Fix] Speacial character issue in searching project in sales invoice (#15220) 2018-08-27 11:43:57 +05:30
Faris Ansari
c4e38ffd4d Remove hub page (#15195) 2018-08-23 11:09:31 +05:30
Shreya Shah
be7703387d Fetch reserved qty (#15182)
* Fetch reserved qty

* Update get_item_details.py
2018-08-22 14:45:22 +05:30
rohitwaghchaure
b800382abf [Fix] Due to incorrect conversion factor user not able to make purchase return entry (#15163) 2018-08-20 17:50:31 +05:30
rohitwaghchaure
e689a903d8 Allowed data import for Assessment Result (#15168) 2018-08-20 17:50:04 +05:30
rohitwaghchaure
ecc6af9d2a [Fix] Total materials consumed cost not consider in the calculation of Gross Margin in project (#15171) 2018-08-20 17:39:54 +05:30
rohitwaghchaure
5c5688b374 Added provision to disabled in stock in products settings (#15133) 2018-08-16 10:33:28 +05:30
Shreya Shah
80f30094fb Fix error msg (#15146) 2018-08-16 10:29:16 +05:30
rohitwaghchaure
6fb2117767 Allow to make budget for the same cost center with different account (#15149) 2018-08-16 10:22:06 +05:30
Shreya Shah
0631aed3d9 Discount amount field in all transactions' child tables (#15124)
* Add discount_amount and base_discount_amount in Sales Invoice Item

* Add patch for existing documents

* Discount amount field in all child tables of Purchase and Selling

* Remove console statements
2018-08-14 10:51:48 +05:30
rohitwaghchaure
88b0a1305f Code optimization for accounts receivable report to avoid timeout error (#15114)
* Code optimization for accounts receivable report to avoid timeout error

* Added index for party_type
2018-08-14 10:51:13 +05:30
Saurabh
9e98fdfc6e Merge branch 'hotfix' 2018-08-13 13:15:56 +05:30
Saurabh
cd6b955b99 bumped to version 10.1.48 2018-08-13 13:45:56 +06:00
Saurabh
bfd26b7084 Merge pull request #15131 from rohitwaghchaure/project_task_custom_field_not_copying
Project task custom field not copying and error on project
2018-08-13 12:15:40 +05:30
Rohit Waghchaure
18960c7757 Project task custom field not copying and error on project 2018-08-13 11:40:11 +05:30
Saurabh
9a7838265d Merge branch 'hotfix' 2018-08-10 17:07:01 +05:30
Saurabh
57d3c93e6b bumped to version 10.1.47 2018-08-10 17:37:01 +06:00
rohitwaghchaure
a0b846fb88 [Minor] Added condition for get_bank_cash_account (#15112) 2018-08-09 15:51:38 +05:30
rohitwaghchaure
8356d4b892 [Fix] disable_rounded_total not found error (#15113) 2018-08-09 15:51:11 +05:30
rohitwaghchaure
ba62013cbb [Fix] Not able to delete the task even if task removed from the project (#15105)
* [Fix] Not able to delete the task even if task removed from the project

* [Fix] Custom field's data in task not updating from the project
2018-08-09 15:50:23 +05:30
rohitwaghchaure
59de1dae6a [Fix] Math domain error (#15107) 2018-08-09 10:58:37 +05:30
Saurabh
91cecf8eac Merge branch 'hotfix' 2018-08-07 12:55:51 +05:30
Saurabh
6ec558bd59 bumped to version 10.1.46 2018-08-07 13:25:51 +06:00
Shreya Shah
11dd3ffdb5 Force delete item on deletion of Lab test template (#15079) 2018-08-06 14:43:00 +05:30
Shreya Shah
f0ef673498 Accounts receivable aging based on supplier due date (#15080)
* Accounts receivable aging based on supplier due date (#13801)

* Remove spaces
2018-08-06 14:42:35 +05:30
rohitwaghchaure
57d07d6b8e Merge pull request #15097 from rohitwaghchaure/incorrect_tax_amount_in_report
[Fix] Incorrect tax amount calculation because of same fieldname in the code
2018-08-06 14:32:44 +05:30
rohitwaghchaure
fc682c86c6 [Fix] Inactive student validation issue while disabling the student group (#15095) 2018-08-06 14:29:46 +05:30
Rohit Waghchaure
15f52e7b71 [Fix] Incorrect tax amount calculation because of same fieldname in the code 2018-08-06 14:29:34 +05:30
Ameya Shenoy
26bfede116 Merge pull request #15078 from rohitwaghchaure/task_email_alert_not_working_from_project
Fix] Task's email alert on status change not working if we change the task status from the project form
2018-08-06 12:33:07 +05:30
Rohit Waghchaure
86217ca96c [Fix] Task email alert on status change not working if we change the task status from the project form 2018-08-02 16:41:53 +05:30
rohitwaghchaure
ae4ff5a403 [Fix] In words showing grand total instead of rounded total (#15065) 2018-08-01 18:09:51 +05:30
rohitwaghchaure
0452b405f4 [Fix] Not able to submit the expense claim (#15057) 2018-08-01 17:45:51 +05:30
rohitwaghchaure
dc7004e083 [Fix] Patient Appointment Calendar not showing data properly (#15052) 2018-07-31 16:01:02 +05:30
Nabin Hait
ebdefade9b Merge branch 'hotfix' 2018-07-31 12:18:23 +05:30
Nabin Hait
e9afbfde76 bumped to version 10.1.45 2018-07-31 12:48:22 +06:00
rohitwaghchaure
086da451ca Removed academic term from validation to check duplicate program enrollement (#15046) 2018-07-30 19:11:14 +05:30
rohitwaghchaure
91d2ace9bb Account no + account name in trial balance and financial statements reports (#15038) 2018-07-30 10:38:51 +05:30
Shreya Shah
91a9ee5179 Merge accounts functionality (#14993)
* Add dialog to merge accounts

* Add conditions and merge functionality

* Fix travis

* Add test case

* Add more test scenarios
2018-07-28 10:26:11 +05:30
Nabin Hait
11137850cb Merge branch 'hotfix' 2018-07-27 12:35:42 +05:30
Nabin Hait
584153a1b1 bumped to version 10.1.44 2018-07-27 13:05:42 +06:00
Shreya Shah
eed0a4e2df Do not copy remarks field while duplicating (#15023) 2018-07-27 11:26:35 +05:30
FinByz Tech Pvt. Ltd
f5cc1bd44c Created Eway Bill Report (#14926)
* Created Eway Bill Report

* Field value changes

* Changed module from Stock to Regional

* Added comments and minor fix

* minor fix
2018-07-27 11:21:42 +05:30
Yaqin Shurrab
cc56ff5c37 Get the correct Summation of Closing Balances (#14990)
Fix total raw values for Closing Credit and Closing Debit
2018-07-27 11:13:00 +05:30
rohitwaghchaure
20d3bef3c3 [Fix] Deducted tax amount adding up in the total amount in the GST Itemised Purchase Register report (#14994) 2018-07-27 11:03:53 +05:30
Shreya Shah
1f4c263a63 [minor] Program Enrollment Tool (#15013)
* Make academic term field mandatory

* Add disabled field to Student Group

* Mandatory check in Education Settings for Academic Term

* Fix as per review
2018-07-27 10:59:14 +05:30
Nabin Hait
d0a2b1619b Optimization for marking student attendance 2018-07-27 10:51:55 +05:30
rohitwaghchaure
0fe6ced99d [Fix] Valuation rate for serialized items (#15017) 2018-07-27 10:33:30 +05:30
Nabin Hait
e50e0e4b30 Update repost_reserved_qty_for_production.py 2018-07-25 17:49:47 +05:30
Shreya Shah
cd717e422f Modify renaming process of Account (#14839)
* Disable renaming for Account Master

* Update account name along with account number

* Fix as per suggestions

* Update account.js

* Fix typo

* Remove after_rename and before_rename methods

* Modify test case

* Modify field placement

* Remove unused method
2018-07-23 14:15:20 +05:30
rohitwaghchaure
6b862fcae5 [Fix] Rounded total is not working in the purchase receipt (#14984) 2018-07-23 13:02:07 +05:30
Zarrar
a22e0d0c99 return empty if no stock ledger entry found (#14968) 2018-07-23 11:31:04 +05:30
Saurabh
8ca5940f76 Merge branch 'hotfix' 2018-07-18 16:24:54 +05:30
Saurabh
6c46b4edc4 bumped to version 10.1.43 2018-07-18 16:54:54 +06:00
Shreya Shah
8395a7ad6f Modifications in last purchase rate button (#14948)
* Make last purchase rate button visible until submitted

* Move buttons

- Get last purchase rate and link to material request buttons moved to toolbar under Tools button

* Remove disable fetch last rate functionality

* Make last purchase rate field read_only
2018-07-18 12:27:27 +05:30
rohitwaghchaure
6863b03790 Naming series increase even if there is an exception while saving the invoice from the backend (#14938) 2018-07-17 17:20:15 +05:30
rohitwaghchaure
a76067eea1 [Fix] Per billed showing as 100% in the sales order even if sales return has made against the sales order (#14899)
* [Fix] Per billed showing as 100% in the sales order even if sales return has made against the sales order

* Added test cases
2018-07-17 16:50:50 +05:30
rohitwaghchaure
216f9373c9 Provision to select the cost center in the asset (#14934) 2018-07-17 16:47:51 +05:30
rohitwaghchaure
5fe88ea93e [Fix] Not able to update the current value of the prefixes which are defined in the autoname field (#14918) 2018-07-17 12:45:25 +05:30
Shreya Shah
fbeab5bf73 Show opening balance of leaves (#14925)
* Show opening balance of leaves

* Update employee_leave_balance.py
2018-07-17 11:59:51 +05:30
rohitwaghchaure
a3e070bc6b [Fix] Invoices not showing in the gross profit report against which sales return entry has created (#14914) 2018-07-16 18:11:19 +05:30
rohitwaghchaure
3ffe89659a [Fix] System always fetches the payment terms template from the company even if it's removed from the sales invoice (#14879) 2018-07-13 17:40:48 +05:30
Ameya Shenoy
5c3b69476d shift to self-hosted frankfurter api (#14792) 2018-07-13 12:46:07 +05:30
Nabin Hait
da17ceea73 patch fixes 2018-07-13 12:04:06 +05:30
rohitwaghchaure
2d84945839 [Fix] Stock reconciliation wrong difference amount calculation (#14893) 2018-07-13 11:07:27 +05:30
Shreya Shah
8dc4c945dc Fix UX (#14862) 2018-07-11 14:36:49 +05:30
rohitwaghchaure
cc9c7d5e2a [Fix] GSTIN not displaying in the address print (#14855)
* [Fix] GSTIN not displaying in the address print

* Made changes in the patch and set Patch as False

* Update update_address_template_for_india.py
2018-07-10 15:41:42 +05:30
rohitwaghchaure
07d0e9a2b2 Don't show disabled items in the stock balance report (#14851) 2018-07-09 16:56:41 +05:30
Saurabh
f38d6d9c44 Merge branch 'hotfix' 2018-07-09 15:53:50 +05:30
Saurabh
07bb1811af bumped to version 10.1.42 2018-07-09 16:23:50 +06:00
rohitwaghchaure
f07462860b Merge pull request #14846 from shreyashah115/fix-digest
Filter out pending orders based on company
2018-07-09 14:48:13 +05:30
rohitwaghchaure
720b06495c [Fix] Not able to save project (#14848) 2018-07-09 13:57:16 +05:30
Shreya
83ad646af4 Filter out pending orders based on company 2018-07-09 12:14:03 +05:30
rohitwaghchaure
8179bcbabd [Fix] Code cleanup (#14843) 2018-07-09 09:29:40 +05:30
rohitwaghchaure
6be8bea934 Provision to view return entries in Sales Person-wise Transaction Summary (#14830) 2018-07-08 19:25:13 +05:30
Saurabh
0b9129e519 Merge branch 'hotfix' 2018-07-06 13:02:58 +05:30
Saurabh
778e06d0ee bumped to version 10.1.41 2018-07-06 13:32:57 +06:00
rohitwaghchaure
3f5e80ebe3 Allow bulk edit for the sales invoice item (#14826) 2018-07-06 12:39:04 +05:30
rohitwaghchaure
ea943c6fe4 [Fix] Due date validate issue in the POS (#14825) 2018-07-06 12:28:58 +05:30
rohitwaghchaure
82a9fde921 Added compact print option for the material request (#14799) 2018-07-06 10:40:51 +05:30
Saurabh
b35721029b Merge pull request #14820 from saurabh6790/fix_task_status
[fix] Add Overdue status in Project Task
2018-07-06 05:54:47 +05:30
Saurabh
f403031449 [fix] Add Overdue status in Project Task 2018-07-05 19:38:59 +05:30
rohitwaghchaure
25f36489b3 Merge pull request #14805 from rohitwaghchaure/pos_ignore_pricing_issue_online
[Fix] POS Profile ignore pricing rule not working for online pos
2018-07-04 16:26:48 +05:30
Rohit Waghchaure
5005e467a0 [Fix] POS Profile ignore pricing rule not working for online pos 2018-07-04 12:37:38 +05:30
Zarrar
68a148e293 half_day enable/disable check (#14795) 2018-07-03 17:00:38 +05:30
rohitwaghchaure
205eae322b [Fix] BOM replace timeout issue (#14782) 2018-07-03 15:06:38 +05:30
Ameya Shenoy
935f4a474b Prevent creation of more than 500 item variants (#14790) 2018-07-03 10:48:59 +05:30
Shreya Shah
aa62a62bb0 Add VAT related fields after printing settings fields (#14773) 2018-07-03 10:28:20 +05:30
Nabin Hait
104f62090d Add filters for cost center in Budget Variance report 2018-06-29 12:25:03 +05:30
Manas Solanki
3ff7f79cc7 Merge pull request #14740 from manassolanki/fix-20
[minor] fix for the args in the frm.call
2018-06-28 20:47:25 +05:30
Manas Solanki
89e7f8b387 [minor] fix for the args in the frm.call 2018-06-28 20:44:53 +05:30
Shreya Shah
2fbc8509f5 Fix error message (#14716) 2018-06-28 14:14:28 +05:30
rohitwaghchaure
67d87e29e3 [Fix] Wrong rate calculation in Itemwise sales register report for multi uom (#14690) 2018-06-27 11:22:03 +05:30
Deepak kumar
55cf6c5f7e Membership (#14688)
* Correct the label and field name

* Update membership.json
2018-06-27 09:17:33 +05:30
rohitwaghchaure
f3cf15fa0d [Fix] While saving project getting timeout error (#14672) 2018-06-26 17:06:00 +05:30
Prateeksha Singh
d53d2ed791 Merge pull request #14679 from pratu16x7/hotfix
[fix] yet another python attribute fetch
2018-06-26 12:20:26 +05:30
Prateeksha Singh
34aeefc0a1 [fix] yet another python attribute fetch 2018-06-26 12:18:29 +05:30
Shreya Shah
d8031d1a53 Clear child table before appending (#14648) 2018-06-25 10:34:55 +05:30
Ameya Shenoy
1098755d26 Merge branch 'hotfix' 2018-06-22 05:10:27 +00:00
Ameya Shenoy
774f676a25 bumped to version 10.1.40 2018-06-22 05:10:27 +00:00
Ameya Shenoy
1629393618 Merge pull request #14628 from Zlash65/fix-pe
Expense Claim - Payment Entry related fix
2018-06-21 18:49:50 +05:30
Zlash65
4cf46edabc expense_claim related fix in payment entry
outstanding amount calculation fix, manual entry of expense trigger calculation of allocation added
2018-06-21 15:18:13 +05:30
Saurabh
e6498996fa Merge branch 'hotfix' 2018-06-20 15:21:40 +05:30
Saurabh
98b7bb5679 bumped to version 10.1.39 2018-06-20 15:51:40 +06:00
Zarrar
99017b173d naming for asset maintenance task should be task name (#14607) 2018-06-20 14:53:13 +05:30
Zarrar
42f2d1a7a8 fix incase no customer fetched (#14596) 2018-06-20 10:50:11 +05:30
Nabin Hait
a125a6199c Allowed paid amount against debit/credit note 2018-06-19 12:07:02 +05:30
Zarrar
ba1cdc6c57 fix opening invoice related authorization control - item=None (#14567) 2018-06-19 10:45:47 +05:30
Nabin Hait
875c941f3d fixes in setting itemised tax breakup 2018-06-18 17:41:27 +05:30
Nabin Hait
8eeb5694ba Fixed qty in item-wise sales history report 2018-06-18 17:41:27 +05:30
Nabin Hait
0bef91c241 minor fix in item type validation 2018-06-18 17:41:27 +05:30
Nabin Hait
ae02209b6a Removed autoname of child table 2018-06-18 17:41:27 +05:30
Zarrar
e0adb6bbd6 cost_center overridden by company's default fix in SI (#14560) 2018-06-18 15:49:12 +05:30
Manas Solanki
efa191c72e [minor fix] change the unicode/str to the datetime obejct (#14534) 2018-06-15 18:04:12 +05:30
Ameya Shenoy
40fe3a2cdf Merge branch 'hotfix' 2018-06-15 09:29:56 +00:00
Ameya Shenoy
ed77429496 bumped to version 10.1.38 2018-06-15 09:29:56 +00:00
Manas Solanki
c7afbea708 Update bom.py (#14524) 2018-06-14 17:30:26 +05:30
Shreya Shah
dd8fba6783 Do not check for batch on cancellation (#14506) 2018-06-14 11:49:45 +05:30
Saurabh
8e74df09a4 [fix] On deletion of salary slip decrease the series count (#14508) 2018-06-14 11:47:21 +05:30
Shreya Shah
3d73a6f7f2 Fetch details from Journal Entry in Accounts Payable report (#14495)
* Fetch bill_no, bill_date from Journal Entry

* Fix as per suggestion

* Fetch details only if bill_no exists
2018-06-13 16:33:06 +05:30
FinByz Tech Pvt. Ltd
46c8ccc6a8 Fix conflict for taxable value having same item in GSTR-1 Report (#14492)
* Update gstr_1.py

Merge conflict for taxable value having same item

* Update gstr_1.py

* Minor Fix

* Update gstr_1.py
2018-06-13 15:34:17 +05:30
Prateeksha Singh
5d0674a23a Merge pull request #14452 from pratu16x7/hotfix
[hotfix][enhance][tax-breakup] store itemized tax by item_name when possible
2018-06-12 17:42:01 +05:30
Prateeksha Singh
a831868d02 Merge pull request #14460 from chdecultot/hotfix_customer
Customer timeline data hotfix
2018-06-11 16:31:17 +05:30
Charles-Henri Decultot
943dc09f29 Customer timeline data hotfix 2018-06-11 09:42:05 +00:00
Prateeksha Singh
ea7533fa75 [tax-breakup] store itemized tax by item_name when can 2018-06-11 13:31:33 +05:30
Shreya Shah
b9399d8781 Cancel attendance if leave application is cancelled (#14372)
* Cancel attendance if leave application is cancelled

* Fix as per review
2018-06-08 11:24:08 +05:30
Zarrar
8cd0f67b25 query fix if name contains apostrophe (#14370) 2018-06-07 16:48:31 +05:30
Zarrar
32a118d68c fix precision in stock entry (#14366) 2018-06-06 15:06:52 +05:30
Ameya Shenoy
a02d5d1104 Merge branch 'hotfix' 2018-06-06 05:41:37 +00:00
Ameya Shenoy
36cd433999 bumped to version 10.1.37 2018-06-06 05:41:37 +00:00
Shreya Shah
6ff3a094e2 Fix currency exchange tests (#14356) 2018-06-05 14:16:10 +05:30
rohitwaghchaure
50d8c4a10f [Fix] Not able to save purchase invoice, due to invalid condition (#14355) 2018-06-05 13:08:10 +05:30
Zarrar
7c088ff623 dont validate items if item_code not found (#14344)
item_code field is not set when created using invoice creation tool
2018-06-05 10:32:09 +05:30
rohitwaghchaure
7cf01e7c75 Replaced fixer api with exchangeratesapi (#14347) 2018-06-05 10:30:20 +05:30
Zarrar
fc03a0463c [Fix] Validate items for saleable, purchaseable or subcontractable in transactions (#14316)
* validate items to see if they are saleable

* check if items are subcontractable or saleable

* improvise name,error message and code
Validate type function validates item if they are of proper type for that transaction and throws descriptive error.
2018-06-04 12:52:52 +05:30
rohitwaghchaure
5ecc26bf15 [Fix] get_shipping_address() takes at least 1 argument (0 given) (#14328) 2018-06-04 11:00:24 +05:30
rohitwaghchaure
c1cf495a93 [Fix] Special character issue (#14322) 2018-06-03 16:00:31 +05:30
rohitwaghchaure
ce642d73cb [Fix] Special character issue while upadting customer group in customer (#14312) 2018-06-01 15:11:21 +05:30
rohitwaghchaure
2fa057e4ad [Fix] Expense claim showing status as Unpaid even if Total Advance Amount and Total Sanctioned Amount is same (#14311) 2018-06-01 15:10:55 +05:30
Zarrar
7e0e85912b item_name not fetched in packing slip (#14310) 2018-06-01 15:10:33 +05:30
Saurabh
defecd3785 Merge branch 'hotfix' 2018-05-31 17:24:53 +05:30
Saurabh
fccf7f2a68 bumped to version 10.1.36 2018-05-31 17:54:53 +06:00
Ameya Shenoy
cce7189b4f Added issue and PR Templates (#14300) 2018-05-31 08:42:52 +05:30
rohitwaghchaure
31a96d2a3f [Fix] System not fetching default warehoue defined in pos profile for packing materials of product bundle item (#14287) 2018-05-30 18:13:47 +05:30
Zarrar
39c0add5a2 query fix sales-person-target-variance-item-group-wise (#14271) 2018-05-30 11:56:58 +05:30
Zarrar
58200182b4 update timeline data form Activity Log (#14276)
Documents updated are stored in Activity Log rather than Communication
2018-05-30 11:56:23 +05:30
Ameya Shenoy
c2c73ae96a [minor] removed vim swap file (#14277) 2018-05-30 11:55:38 +05:30
Shreya Shah
ae95a8aa15 Update status in Purchase Receipt (#14257)
* Update status on submission if per_billed = 100

* Add patch to update existing records
2018-05-28 18:24:28 +05:30
Zarrar
b9f54ca946 [Enhance] Group same items during printing Delivery Note, Invoices, etc (#14250)
* add doctypes allowed to group items, average the rate

* add check field to group items during print

* call common before_print in delivery note

* fix precision issue while calculating average
2018-05-28 17:41:09 +05:30
rohitwaghchaure
a8c6ec27c0 Merge pull request #14252 from rohitwaghchaure/leaderboard_translation_issue
[Fix] Translation issue in leaderboard
2018-05-28 15:51:00 +05:30
Saurabh
3c1b153cdb Merge pull request #14111 from netchampfaris/stock-ledger-report-hotfix
[fix] Stock Ledger report item filter
2018-05-28 15:23:21 +05:30
Rohit Waghchaure
06f91e2dc1 [Fix] Translation issue in leaderboard 2018-05-28 14:43:17 +05:30
Shreya Shah
13f39eb821 Display rate on the basis of stock UOM (#14246) 2018-05-28 11:50:28 +05:30
rohitwaghchaure
a8fb2db001 [Fix] If two po consolidated in one purchase invoice, Total Net Weight not get summed (#14230) 2018-05-26 09:23:02 +05:30
Ranjith Kurungadam
27cf190269 healthcare fix - str encode to utf-8 (#14213) 2018-05-24 17:15:22 +05:30
Ameya Shenoy
7ad556cd4c Merge branch 'hotfix' 2018-05-24 08:45:12 +00:00
Ameya Shenoy
475729cefe bumped to version 10.1.35 2018-05-24 08:45:12 +00:00
Manas Solanki
f7713ebfa7 [optimize] introduce two filter in the report in order to handle large item master data (#14193) 2018-05-23 19:43:04 +05:30
Ameya Shenoy
92640cc899 Merge branch 'hotfix' 2018-05-22 09:06:38 +00:00
Ameya Shenoy
826f020862 bumped to version 10.1.34 2018-05-22 09:06:38 +00:00
Zarrar
93a186aa11 fetch customer_gstin or billing_address_gstin optionally (#14075) 2018-05-22 09:16:42 +05:30
rohitwaghchaure
742d3e5549 [Fix] General ledger default_currency issue for member party type (#14172) 2018-05-22 09:10:01 +05:30
Prateeksha Singh
bcbe32ce7c Merge pull request #14169 from pratu16x7/hotfix
[hotfix][charts] update, without new build system
2018-05-21 18:31:39 +05:30
Prateeksha Singh
b434f2687e [charts] update, without new build system 2018-05-21 18:04:50 +05:30
Manas Solanki
a752eca82c Merge pull request #14163 from manassolanki/fix-20
[fix] don't update the modified of item price while updating item
2018-05-21 16:37:01 +05:30
rohitwaghchaure
37da7d7d05 Merge pull request #14162 from rohitwaghchaure/permissions_issue_leave_application
[Fix] Permission issue while saving leave application
2018-05-21 16:02:58 +05:30
Manas Solanki
b5d9b38dee don't update the modified of the item price 2018-05-21 15:40:51 +05:30
Rohit Waghchaure
11e2a9ac90 [Fix] Permission issue while saving leave application 2018-05-21 15:39:38 +05:30
rohitwaghchaure
1275ea5123 Merge pull request #14154 from rohitwaghchaure/set_default_leave_approver
Set leave approver in the leave application
2018-05-21 11:58:41 +05:30
Rohit Waghchaure
812224e56e Set leave approver in the leave application 2018-05-20 21:21:33 +05:30
Gaurav Naik
8f17281011 Initialized dynamic link on Warehouse (#14135)
* Initialized dynamic link for Warehouse

* Codacy Fixes
2018-05-20 10:39:14 +05:30
Prateeksha Singh
8233cb11ed Merge pull request #14124 from pratu16x7/hotfix
[item-query] change order of description terms, name first
2018-05-17 17:32:54 +05:30
Prateeksha Singh
984a7a7e61 [item-query] change order of description terms, name first 2018-05-17 17:29:36 +05:30
rohitwaghchaure
b5cc946771 Merge pull request #14122 from shreyashah115/fixes
Fix in marking attendance from Leave Application
2018-05-17 17:16:57 +05:30
Shreya
65dd1f6b4c Mark attendance only if to_date <= nowdate in Leave Application 2018-05-17 17:13:56 +05:30
Prateeksha Singh
7c9a6eba3f Merge pull request #14116 from rohitwaghchaure/project_heatmap_issue
[Fix] Heatmap issue in the project
2018-05-17 15:42:58 +05:30
Rohit Waghchaure
f2ccde0454 [Fix] Heatmap issue in the project 2018-05-17 15:40:32 +05:30
Faris Ansari
9e4889d756 [fix] Stock Ledger report item filter
- breaks when Item Code contains % symbol
2018-05-17 12:18:28 +05:30
Manas Solanki
b81ece9ddf Merge pull request #14076 from chdecultot/pricing_rule
Missing parentheses in price list rate determination
2018-05-16 14:55:32 +05:30
Charles-Henri Decultot
2f822476dd Removal of debugging print 2018-05-16 08:40:16 +00:00
Charles-Henri Decultot
dcfe19d868 Missing parentheses in price list rate determination 2018-05-16 08:34:41 +00:00
Shreya Shah
4f40b2dca5 [Fix] Sales Person Reports (#13987)
* Fix Sales Person Reports
- Show quantity and amounts based on the delivered quantities if the Sales Order has been closed and all quantities weren't considered for further transactions.

* Fix codacy

* Modify as per the review comment
2018-05-16 11:22:59 +05:30
Manas Solanki
1b48fde986 Make the communication from the issue webform (#14015) 2018-05-16 10:47:02 +05:30
Rushabh Mehta
33db332eca Revert "apply sorting for make multiple variant attributes (#14060)" (#14065)
This reverts commit 257e18b640.
2018-05-16 10:43:58 +05:30
lasalesi
257e18b640 apply sorting for make multiple variant attributes (#14060) 2018-05-16 10:42:42 +05:30
Saurabh
292f46fec0 Merge branch 'hotfix' 2018-05-15 14:59:36 +05:30
Saurabh
78a0be666f bumped to version 10.1.33 2018-05-15 15:29:36 +06:00
Saurabh
ce4f520908 Merge pull request #14042 from saurabh6790/patch_fix_15_05
[fix] if UOM and Warehouse link is invalid then set blank values
2018-05-15 14:58:12 +05:30
Saurabh
29160441bb [fix] if UOM and Warehouse link is invalid then set blank values 2018-05-15 14:56:18 +05:30
Saurabh
1b18bba04a Merge branch 'hotfix' 2018-05-15 12:58:15 +05:30
Saurabh
f8c26bb778 bumped to version 10.1.32 2018-05-15 13:28:15 +06:00
Saurabh
ccd0617e19 Merge pull request #14017 from netchampfaris/apply-price-list-hotfix
[fix] apply price list
2018-05-15 11:25:08 +05:30
Saurabh
bf10d0f98b Merge pull request #14031 from shreyashah115/leave-balance
[Bug] Clear leave balance in Leave Application
2018-05-15 11:11:49 +05:30
Shreya
dbb67fb4fd Clear leave balance on changing leave type 2018-05-14 23:02:09 +05:30
Faris Ansari
404f39d373 [fix] apply price list
in_apply_price_list flag remains true if server exception occurs
2018-05-14 15:46:45 +05:30
Shreya Shah
bbee9b6cc4 [Enhancement] Monthly Attendance Report (#13970)
* Update Attendance on Approval of Leave

* Separate out leaves on the basis of its type

* Remove commented code

* Make attendance records if not found

* Fix Codacy

* Replace bad code in attendance.py
2018-05-14 14:30:58 +05:30
Faris Ansari
69b0535e10 [fix] Incorrect currency conversion in Itemised Tax Breakup (#14006) 2018-05-14 14:19:31 +05:30
rohitwaghchaure
7f63c1ad7c Merge pull request #14014 from rohitwaghchaure/hotfix_production_order_name_issue
[Fix] 'ProductionOrder' object has no attribute 'set_work_order_operations'
2018-05-14 14:04:09 +05:30
Rohit Waghchaure
ebe1ebead2 [Fix] 'ProductionOrder' object has no attribute 'set_work_order_operations' 2018-05-14 13:21:45 +05:30
Faris Ansari
f2b3307136 Remove escaped customer string (#13986)
- no need to escape strings that are passed to the values parameter of the sql method
- this query was failing for inputs like "D'Arby" which have quotes
2018-05-11 21:07:27 +05:30
Nabin Hait
9d215c2d9b Set operations on production order while making from Material Request 2018-05-09 18:32:54 +05:30
Vishal Dhayagude
3cf0d51e65 [fix] Compounding error in task weight (#13958)
* [fix] Compounding error in task weight

* [minor] minor changes

* [fix] Requested Changes added
2018-05-09 10:42:39 +05:30
Nabin Hait
9fc5ddc26e Merge branch 'hotfix' 2018-05-08 16:31:38 +05:30
Nabin Hait
0ff31f0ebf bumped to version 10.1.31 2018-05-08 17:01:38 +06:00
Saurabh
40349f4b00 [fix] add stock entry link on Material Request Dashboard (#13950) 2018-05-08 15:23:51 +05:30
Saurabh
b36517158b [fix] cheque print template coordinates (#13959) 2018-05-08 15:23:29 +05:30
Manas Solanki
3b9720f0be Merge pull request #13952 from manassolanki/minor-report-fix
[minor] fix for the student report card
2018-05-08 12:43:43 +05:30
Manas Solanki
cf26b2ca1c [minor] fix for the student report card 2018-05-08 12:39:02 +05:30
Nabin Hait
02a40e9d7b Merge branch 'hotfix' 2018-05-05 14:33:33 +05:30
Nabin Hait
ea199f9cd9 bumped to version 10.1.30 2018-05-05 15:03:33 +06:00
Nabin Hait
161f35a687 Update sales_invoice.py 2018-05-05 14:32:31 +05:30
Nabin Hait
fcb984b294 Merge branch 'hotfix' 2018-05-05 12:13:29 +05:30
Nabin Hait
723fe8fb1b bumped to version 10.1.29 2018-05-05 12:43:29 +06:00
Ameya Shenoy
47c0c8ba49 removed bad code and made compatible with pip 10 (#13805) 2018-05-04 19:20:20 +05:30
Rohit Waghchaure
3e0a937cb8 [Fix] Tax not changes when user change the POS profile in the sales invoice 2018-05-04 19:20:20 +05:30
Jamsheer
bd63f0056a Patient medical record updation and deletion fixes (#13891) 2018-05-04 18:13:28 +05:30
Shreya Shah
55daa9cd24 fix taxable amount for same items (#13927) 2018-05-04 18:01:23 +05:30
Shreya Shah
764b9bfeba cint for Item field has_variants (#13916)
* convert none type value to int

* Fix typo
2018-05-04 17:58:36 +05:30
Nabin Hait
62b985d405 [fix] Update show_in_website in template 2018-05-04 12:21:15 +05:30
Saurabh
ed393d1025 [fix] consider user permissions in leave application calendar view (#13902)
* [fix] consider user permissions in leave application calendar view

* add hr settings to control leave calendar view

* add patch
2018-05-03 18:52:25 +05:30
Nabin Hait
ed376cacc8 Set Qty in transactions based on serial no via Stock Settings (#13897) 2018-05-03 16:24:52 +05:30
Saurabh
7461806b1c Merge pull request #13892 from codingCoffee/travis
dark magic to revive travis
2018-05-02 23:23:07 +05:30
Ameya Shenoy
bb7c5ac0f8 dark magic to revive travis
It seems that some process inside travis is using port no 9000. Hence
adding this line in the travis.yml to change common_site_config.json and
use port no 9001 for socket_io
2018-05-02 17:32:39 +05:30
Saurabh
0272fc05bf Merge branch 'hotfix' 2018-05-02 14:48:09 +05:30
Saurabh
4f6b68fef2 bumped to version 10.1.28 2018-05-02 15:18:09 +06:00
Faris Ansari
eae2ddac69 validate_conversion_rate in taxes_and_totals (#13880) 2018-05-02 12:19:30 +05:30
Prateeksha Singh
99be9d17d5 Merge pull request #13850 from netchampfaris/msgprint-to-alert
Change msgprint to alert
2018-05-01 18:52:49 +05:30
Faris Ansari
5df63e36d4 Merge branch 'hotfix' of https://github.com/frappe/erpnext into hotfix 2018-05-01 10:52:15 +05:30
Faris Ansari
bd99606a14 Change msgprint to unobtrusive alert 2018-05-01 10:52:02 +05:30
Zarrar
b0a46f397a display customer's name while printing receivable report (#13830) 2018-04-30 19:40:18 +05:30
Prateeksha Singh
53c9b63c0b Merge pull request #13842 from pratu16x7/hotfix
[fix] setup_website, fixes #11143
2018-04-30 18:21:53 +05:30
Prateeksha Singh
9b2078feab [fix] setup_website, fixes #11143 2018-04-30 18:11:20 +05:30
Faris Ansari
30304e68ff [fix] Current stock qty calculation in case of different UOM 2018-04-30 15:44:49 +05:30
Zarrar
6bc500bffa [Minor] Validate dates in Salary Structure (#13807)
* validate date

* fix date trigger issue
2018-04-30 11:14:09 +05:30
Faris Ansari
8be895091e Set is_pos to 0 in Opening Invoice Tool (#13810) 2018-04-30 11:13:06 +05:30
Ameya Shenoy
f5f8a1f288 i still don't know why we're still using travis (#13817) 2018-04-30 11:10:39 +05:30
Gaurav Naik
c925a38f79 Ignore mandatory for default warehouses (#13812) 2018-04-27 15:31:11 +05:30
Prateeksha Singh
c23230faea Merge pull request #13786 from pratu16x7/hotfix
[fix] featured product thumbnail
2018-04-25 13:04:19 +05:30
Prateeksha Singh
6855b87f76 [fix] featured product thumbnail 2018-04-25 13:03:11 +05:30
Saurabh
07d030208f Merge branch 'hotfix' 2018-04-25 12:46:48 +05:30
Saurabh
47f6e32920 bumped to version 10.1.27 2018-04-25 13:16:48 +06:00
Saurabh
7bd1453f8f Merge pull request #13785 from rohitwaghchaure/fix_patch_pos_taxes
[Fix] POS Patch
2018-04-25 12:44:20 +05:30
Rohit Waghchaure
bf416cfbf8 [Fix] POS Patch 2018-04-25 12:32:22 +05:30
Saurabh
67918fff32 Merge branch 'hotfix' 2018-04-25 11:31:48 +05:30
Saurabh
132dac9712 bumped to version 10.1.26 2018-04-25 12:01:48 +06:00
rohitwaghchaure
57914f140e [HotFix] Taxes not adding in POS sales invoice (#13776) 2018-04-24 19:19:47 +05:30
Saurabh
ede0af97cd Merge branch 'hotfix' 2018-04-24 12:09:38 +05:30
Saurabh
ad4ede0e23 bumped to version 10.1.25 2018-04-24 12:39:38 +06:00
Saurabh
cfcf9b3832 Merge pull request #13772 from saurabh6790/supp_240418
typo fix
2018-04-24 12:08:38 +05:30
Saurabh
d2065ce3bf typo fix 2018-04-24 12:07:37 +05:30
Rohit Waghchaure
31edddace6 [Fix] Tax not changes when user change the POS profile in the sales invoice 2018-04-24 11:43:31 +05:30
Saurabh
8f29159fb7 Merge branch 'hotfix' 2018-04-24 11:12:07 +05:30
Saurabh
d9f1b539dc bumped to version 10.1.24 2018-04-24 11:42:07 +06:00
Prateeksha Singh
60bd383a25 Merge pull request #13763 from pratu16x7/hotfix
[fix] cal view start end date field discrepancies
2018-04-23 13:34:49 +05:30
Prateeksha Singh
c0ec3c3f7b [fix] cal view start end date field discrepancies 2018-04-23 13:32:59 +05:30
Manas Solanki
60aa1170d5 Merge pull request #13762 from manassolanki/fix-patient-appointment
fixed the gantt view of patient appointment
2018-04-23 12:39:28 +05:30
Manas Solanki
9630aa3d7f fixed the gantt view of patient appointment 2018-04-23 12:37:11 +05:30
Manas Solanki
aa6576c0ea Merge pull request #13755 from Zlash65/typo
[Minor] Typo fix in Leaderboard
2018-04-23 11:09:18 +05:30
Zlash65
fa5ecb066e typo fix in leaderboard 2018-04-22 12:11:01 +05:30
Nabin Hait
c36524ec54 Update chart_of_accounts.py 2018-04-20 11:00:20 +05:30
Saurabh
cba3570cf6 Merge pull request #13734 from rohitwaghchaure/pos_special_character_item_issue
[Fix] Item with special character not adding in the POS cart
2018-04-19 15:58:35 +05:30
Saurabh
5b7503c074 Merge pull request #13691 from saurabh6790/supp_180417_1
[hotfix] multiple fixes
2018-04-19 15:57:35 +05:30
Rohit Waghchaure
8441dd9184 [Fix] Item with special character not adding in the POS cart 2018-04-19 12:55:06 +05:30
Julian Robbins
78869f1e77 Update manual-feedback-request.md (#13709)
Changed wording to reflect current wording of Feedback Request rather than 'Ask a Feedback'
2018-04-18 03:12:30 -08:00
Rushabh Mehta
ff8f1bc88e Revert "removed bad code and made compatible with pip 10 (#13685)" (#13713)
This reverts commit 91b0dce4d8.
2018-04-18 02:57:44 -08:00
Ameya Shenoy
91b0dce4d8 removed bad code and made compatible with pip 10 (#13685) 2018-04-18 02:57:04 -08:00
Zarrar
59f7b8c4a1 issue routing to report (#13710) 2018-04-18 02:56:02 -08:00
Saurabh
2476a8aab9 a[fix] check content before making in condition 2018-04-17 20:45:06 +05:30
Saurabh
46ffbb74ff fix cheque print measurements 2018-04-17 20:44:37 +05:30
Saurabh
492aff2a8b [fix] check if academic_year exists (#13665) 2018-04-17 14:21:40 +05:30
Saurabh
c3fbc04aab Merge branch 'hotfix' 2018-04-17 12:00:19 +05:30
Saurabh
5b866db6bc bumped to version 10.1.23 2018-04-17 12:30:19 +06:00
Saurabh
9fbb8192e1 [fix] do not escape % while using clause (#13677) 2018-04-17 11:56:46 +05:30
Saurabh
ea1408f2e0 [fix] enqueue salary slip print email after completing accounting entries (#13633) 2018-04-15 21:38:49 -08:00
Saurabh
f2a941b1a4 [fix] check if supplier value exists (#13616) 2018-04-15 21:37:14 -08:00
Saurabh
ca1cfd91ea Merge branch 'hotfix' 2018-04-15 12:54:49 +05:30
Saurabh
c3d43e672b bumped to version 10.1.22 2018-04-15 13:24:49 +06:00
Saurabh
e141fdcfcc Merge pull request #13661 from codingCoffee/pip10
Compatibility for pip 10
2018-04-15 12:43:28 +05:30
Ameya Shenoy
7cb8f890bc Compatibility for pip 10
- also some spaces and tabs fixes
2018-04-15 03:43:21 +05:30
Nabin Hait
d6aadef395 Merge branch 'hotfix' 2018-04-13 14:38:23 +05:30
Nabin Hait
11c899bc1f bumped to version 10.1.21 2018-04-13 15:08:22 +06:00
Nabin Hait
00efeb26f4 Email Account field added in Issue 2018-04-13 14:30:26 +05:30
rohitwaghchaure
1129ac711e [Fix] Patch (#13610) 2018-04-12 14:48:23 +05:30
rohitwaghchaure
2ea593bdd8 [Fix] POS Profile data not set in the sales invoice (#13568) 2018-04-12 13:37:08 +05:30
Ahmed Madi
02fd6f56d6 Update leave_application.py (#13575)
Make get_holidays function white listed
2018-04-12 13:31:50 +05:30
rohitwaghchaure
098b444f6f [minor] Toggle required opportunity item table based on with items field (#13584) 2018-04-12 13:26:50 +05:30
rohitwaghchaure
e72bde5159 Removed expired items from the list of POS items (#13582) 2018-04-12 13:26:11 +05:30
Nabin Hait
c10e106f8f Optimization related to large number of items (#13606) 2018-04-12 13:25:03 +05:30
rohitwaghchaure
2c111b7b14 Minor fix (#13600) 2018-04-11 02:20:06 -08:00
267 changed files with 6626 additions and 5942 deletions

68
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,68 @@
---
name: Bug report
about: Create a report to help us improve
---
Issue: Bug report
Our project, as you've probably heard, is getting really popular and truth is we're getting a bit overwhelmed by the activity surrounding it. There are just too many issues for us to manage properly.
**Do the checklist before filing an issue:**
- [ ] Have a usage question? Ask your question on [Discuss Forum](https://discuss.erpnext.com). We use [Discuss Forum](https://discuss.erpnext.com) for usage question and GitHub for bugs.
- [ ] Can you replicate the issue?
- [ ] Is this something you can debug and fix? Send a pull request! Bug fixes and documentation fixes are welcome
**Describe the bug** :chart_with_downwards_trend:
A clear and concise description of what the bug is.
**To Reproduce** :page_with_curl:
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior** :chart_with_upwards_trend:
A clear and concise description of what you expected to happen.
**Screenshots** :crystal_ball:
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):** :cyclone:
- OS:
- [ ] Linux
- [ ] macOS
- [ ] Windows
- [ ] Others? Please mention:
- Browser:
- [ ] Safari
- [ ] Chrome
- [ ] Firefox
- [ ] Other? Please mention:
**Smartphone (please complete the following information):** :iphone: :computer:
- Device:
- [ ] iPhone
- [ ] Android
- Browser:
- [ ] Safari
- [ ] Chrome
- [ ] Firefox
- [ ] Other? Please mention:
**Version Information**
- Which branch are you on?
- [ ] `master` :star2:
- [ ] `develop` :fire:
- Frappe Version:
- ERPNext Version:
**Additional context** :page_facing_up:
Add any other context about the problem here.
**Possible Solution** :bookmark_tabs:
Any idea what might be causing the issue. Or if you have a proposed solution to the problem,
**Please don't be intimidated by the long list of options you've fill. Try to fill out as much as you can. Remember, the more the information the easier it is for us to replicate and fix the issue** :grin:

View File

@@ -0,0 +1,21 @@
---
name: Feature request
about: Suggest an idea for this project
---
Issue: Feature Request
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

28
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,28 @@
Pull-Request
- [ ] Have you followed the guidelines in our Contributing document?
- [ ] Have you checked to ensure there aren't other open [Pull Requests](../pulls) for the same update/change?
- [ ] Have you lint your code locally prior to submission?
- [ ] Have you successfully run tests with your changes locally?
- [ ] Does your commit message have an explanation for your changes and why you'd like us to include them?
- [ ] Docs have been added / updated
- [ ] Tests for the changes have been added (for bug fixes / features)
- [ ] Did you modify the existing test cases? If yes, why?
---
What type of a PR is this?
- [ ] Changes to Existing Features
- [ ] New Feature Submissions
- [ ] Bug Fix
- [ ] Breaking Change
---
- Motivation and Context (What existing problem does the pull request solve):
- Related Issue:
- Screenshots (if applicable, remember, a picture tells a thousand words):
**Please don't be intimidated by the long list of options you've fill. Try to fill out as much as you can. Remember, the more the information the easier it is for us to test and get your pull request merged** :grin:

1
.gitignore vendored
View File

@@ -8,3 +8,4 @@ latest_updates.json
*.egg-info
dist/
erpnext/docs/current
*.swp

BIN
.swp

Binary file not shown.

View File

@@ -11,6 +11,7 @@ install:
- pip install flake8==3.3.0
- flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics
- sudo rm /etc/apt/sources.list.d/docker.list
- sudo apt-get install hhvm && rm -rf /home/travis/.kiex/
- sudo apt-get purge -y mysql-common mysql-server mysql-client
- nvm install v7.10.0
- wget https://raw.githubusercontent.com/frappe/bench/master/playbooks/install.py
@@ -32,6 +33,7 @@ before_script:
- bench reinstall --yes
- bench build
- bench scheduler disable
- sed -i 's/9000/9001/g' sites/common_site_config.json
- bench start &
- sleep 10

View File

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

View File

@@ -49,10 +49,16 @@ frappe.ui.form.on('Account', {
}
if(!frm.doc.__islocal) {
frm.add_custom_button(__('Update Account Number'), function () {
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");
});
}
},
account_type: function (frm) {
if (frm.doc.is_group == 0) {
@@ -98,20 +104,65 @@ frappe.ui.form.on('Account', {
}
},
update_account_number: function(frm) {
merge_account: function(frm) {
var d = new frappe.ui.Dialog({
title: __('Update Account Number'),
title: __('Merge with Existing Account'),
fields: [
{
"label": "Account Number",
"fieldname": "account_number",
"label" : "Name",
"fieldname": "name",
"fieldtype": "Data",
"reqd": 1
"reqd": 1,
"default": frm.doc.name
}
],
primary_action: function() {
var data = d.get_values();
if(data.account_number === frm.doc.account_number) {
frappe.call({
method: "erpnext.accounts.doctype.account.account.merge_account",
args: {
old: frm.doc.name,
new: data.name,
is_group: frm.doc.is_group,
root_type: frm.doc.root_type,
company: frm.doc.company
},
callback: function(r) {
if(!r.exc) {
if(r.message) {
frappe.set_route("Form", "Account", r.message);
}
d.hide();
}
}
});
},
primary_action_label: __('Merge')
});
d.show();
},
update_account_number: function(frm) {
var d = new frappe.ui.Dialog({
title: __('Update Account Number / Name'),
fields: [
{
"label": "Account Name",
"fieldname": "account_name",
"fieldtype": "Data",
"reqd": 1,
"default": frm.doc.account_name
},
{
"label": "Account Number",
"fieldname": "account_number",
"fieldtype": "Data",
"default": frm.doc.account_number
}
],
primary_action: function() {
var data = d.get_values();
if(data.account_number === frm.doc.account_number && data.account_name === frm.doc.account_name) {
d.hide();
return;
}
@@ -120,6 +171,7 @@ frappe.ui.form.on('Account', {
method: "erpnext.accounts.doctype.account.account.update_account_number",
args: {
account_number: data.account_number,
account_name: data.account_name,
name: frm.doc.name
},
callback: function(r) {
@@ -128,6 +180,7 @@ frappe.ui.form.on('Account', {
frappe.set_route("Form", "Account", r.message);
} else {
frm.set_value("account_number", data.account_number);
frm.set_value("account_name", data.account_name);
}
d.hide();
}
@@ -138,4 +191,4 @@ frappe.ui.form.on('Account', {
});
d.show();
}
});
});

View File

@@ -2,7 +2,7 @@
"allow_copy": 1,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
"allow_rename": 0,
"beta": 0,
"creation": "2013-01-30 12:49:46",
"custom": 0,
@@ -40,6 +40,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -68,6 +69,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0,
"width": "50%"
},
@@ -100,6 +102,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -130,6 +133,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -161,6 +165,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -193,6 +198,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -223,6 +229,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -253,6 +260,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -285,6 +293,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -313,6 +322,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0,
"width": "50%"
},
@@ -346,6 +356,7 @@
"reqd": 1,
"search_index": 1,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -379,6 +390,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -411,6 +423,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -444,6 +457,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -474,6 +488,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -503,6 +518,7 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -532,6 +548,7 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -561,6 +578,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}
],
@@ -575,7 +593,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-08-22 17:39:10.711343",
"modified": "2018-07-08 09:47:04.287841",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Account",

View File

@@ -165,53 +165,6 @@ class Account(NestedSet):
super(Account, self).on_trash(True)
def before_rename(self, old, new, merge=False):
# Add company abbr if not provided
from erpnext.setup.doctype.company.company import get_name_with_abbr
new_account = get_name_with_abbr(new, self.company)
if not merge:
new_account = get_name_with_number(new_account, self.account_number)
else:
# Validate properties before merging
if not frappe.db.exists("Account", new):
throw(_("Account {0} does not exist").format(new))
val = list(frappe.db.get_value("Account", new_account,
["is_group", "root_type", "company"]))
if val != [self.is_group, self.root_type, self.company]:
throw(_("""Merging is only possible if following properties are same in both records. Is Group, Root Type, Company"""))
if self.is_group and frappe.db.get_value("Account", new, "parent_account") == old:
frappe.db.set_value("Account", new, "parent_account",
frappe.db.get_value("Account", old, "parent_account"))
return new_account
def after_rename(self, old, new, merge=False):
super(Account, self).after_rename(old, new, merge)
if not merge:
new_acc = frappe.db.get_value("Account", new, ["account_name", "account_number"], as_dict=1)
# exclude company abbr
new_parts = new.split(" - ")[:-1]
# update account number and remove from parts
if new_parts[0][0].isdigit():
# if account number is separate by space, split using space
if len(new_parts) == 1:
new_parts = new.split(" ")
if new_acc.account_number != new_parts[0]:
self.account_number = new_parts[0]
self.db_set("account_number", new_parts[0])
new_parts = new_parts[1:]
# update account name
account_name = " - ".join(new_parts)
if new_acc.account_name != account_name:
self.account_name = account_name
self.db_set("account_name", account_name)
def get_parent_account(doctype, txt, searchfield, start, page_len, filters):
return frappe.db.sql("""select name from tabAccount
where is_group = 1 and docstatus != 2 and company = %s
@@ -252,25 +205,38 @@ def validate_account_number(name, account_number, company):
.format(account_number, account_with_same_number))
@frappe.whitelist()
def update_account_number(name, account_number):
account = frappe.db.get_value("Account", name, ["account_name", "company"], as_dict=True)
def update_account_number(name, account_name, account_number=None):
account = frappe.db.get_value("Account", name, "company", as_dict=True)
if not account: return
validate_account_number(name, account_number, account.company)
frappe.db.set_value("Account", name, "account_number", account_number)
account_name = account.account_name
if account_name[0].isdigit():
separator = " - " if " - " in account_name else " "
account_name = account_name.split(separator, 1)[1]
frappe.db.set_value("Account", name, "account_name", account_name)
if account_number:
frappe.db.set_value("Account", name, "account_number", account_number.strip())
else:
frappe.db.set_value("Account", name, "account_number", "")
frappe.db.set_value("Account", name, "account_name", account_name.strip())
new_name = get_account_autoname(account_number, account_name, account.company)
if name != new_name:
frappe.rename_doc("Account", name, new_name)
frappe.rename_doc("Account", name, new_name, ignore_permissions=1)
return new_name
def get_name_with_number(new_account, account_number):
if account_number and not new_account[0].isdigit():
new_account = account_number + " - " + new_account
return new_account
@frappe.whitelist()
def merge_account(old, new, is_group, root_type, company):
# Validate properties before merging
if not frappe.db.exists("Account", new):
throw(_("Account {0} does not exist").format(new))
val = list(frappe.db.get_value("Account", new,
["is_group", "root_type", "company"]))
if val != [cint(is_group), root_type, company]:
throw(_("""Merging is only possible if following properties are same in both records. Is Group, Root Type, Company"""))
if is_group and frappe.db.get_value("Account", new, "parent_account") == old:
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)
return new

View File

@@ -71,7 +71,7 @@ frappe.treeview_settings["Account"] = {
// financial statements
for (let report of ['Trial Balance', 'General Ledger', 'Balance Sheet',
'Profit and Loss', 'Cash Flow Statement', 'Accounts Payable', 'Accounts Receivable']) {
'Profit and Loss Statement', 'Cash Flow Statement', 'Accounts Payable', 'Accounts Receivable']) {
treeview.page.add_inner_button(__(report), function() {
frappe.set_route('query-report', report, {company: get_company()});
}, __('Financial Statements'));

View File

@@ -165,7 +165,7 @@ def build_account_tree(tree, parent, all_accounts):
tree[child.account_name] = {}
# assign account_type and root_type
if child.account_type:
if child.account_number:
tree[child.account_name]["account_number"] = child.account_number
if child.account_type:
tree[child.account_name]["account_type"] = child.account_type
@@ -175,4 +175,4 @@ def build_account_tree(tree, parent, all_accounts):
tree[child.account_name]["root_type"] = child.root_type
# call recursively to build a subtree for current account
build_account_tree(tree[child.account_name], child, all_accounts)
build_account_tree(tree[child.account_name], child, all_accounts)

View File

@@ -5,6 +5,8 @@ from __future__ import unicode_literals
import unittest
import frappe
from erpnext.stock import get_warehouse_account, get_company_default_inventory_account
from erpnext.accounts.doctype.account.account import update_account_number
from erpnext.accounts.doctype.account.account import merge_account
class TestAccount(unittest.TestCase):
def test_rename_account(self):
@@ -21,21 +23,79 @@ class TestAccount(unittest.TestCase):
self.assertEqual(account_number, "1210")
self.assertEqual(account_name, "Debtors")
frappe.rename_doc("Account", "1210 - Debtors - _TC", "1211 - Debtors 1 - _TC")
new_account_number = "1211-11-4 - 6 - "
new_account_name = "Debtors 1 - Test - "
new_acc = frappe.db.get_value("Account", "1211 - Debtors 1 - _TC",
update_account_number("1210 - Debtors - _TC", new_account_name, new_account_number)
new_acc = frappe.db.get_value("Account", "1211-11-4 - 6 - - Debtors 1 - Test - - _TC",
["account_name", "account_number"], as_dict=1)
self.assertEqual(new_acc.account_name, "Debtors 1")
self.assertEqual(new_acc.account_number, "1211")
frappe.rename_doc("Account", "1211 - Debtors 1 - _TC", "Debtors 2")
self.assertEqual(new_acc.account_name, "Debtors 1 - Test -")
self.assertEqual(new_acc.account_number, "1211-11-4 - 6 -")
new_acc = frappe.db.get_value("Account", "1211 - Debtors 2 - _TC",
["account_name", "account_number"], as_dict=1)
self.assertEqual(new_acc.account_name, "Debtors 2")
self.assertEqual(new_acc.account_number, "1211")
frappe.delete_doc("Account", "1211-11-4 - 6 - Debtors 1 - Test - - _TC")
frappe.delete_doc("Account", "1211 - Debtors 2 - _TC")
def test_merge_account(self):
if not frappe.db.exists("Account", "Current Assets - _TC"):
acc = frappe.new_doc("Account")
acc.account_name = "Current Assets"
acc.is_group = 1
acc.parent_account = "Application of Funds (Assets) - _TC"
acc.company = "_Test Company"
acc.insert()
if not frappe.db.exists("Account", "Securities and Deposits - _TC"):
acc = frappe.new_doc("Account")
acc.account_name = "Securities and Deposits"
acc.parent_account = "Current Assets - _TC"
acc.is_group = 1
acc.company = "_Test Company"
acc.insert()
if not frappe.db.exists("Account", "Earnest Money - _TC"):
acc = frappe.new_doc("Account")
acc.account_name = "Earnest Money"
acc.parent_account = "Securities and Deposits - _TC"
acc.company = "_Test Company"
acc.insert()
if not frappe.db.exists("Account", "Cash In Hand - _TC"):
acc = frappe.new_doc("Account")
acc.account_name = "Cash In Hand"
acc.is_group = 1
acc.parent_account = "Current Assets - _TC"
acc.company = "_Test Company"
acc.insert()
if not frappe.db.exists("Account", "Accumulated Depreciation - _TC"):
acc = frappe.new_doc("Account")
acc.account_name = "Accumulated Depreciation"
acc.parent_account = "Fixed Assets - _TC"
acc.company = "_Test Company"
acc.insert()
doc = frappe.get_doc("Account", "Securities and Deposits - _TC")
parent = frappe.db.get_value("Account", "Earnest Money - _TC", "parent_account")
self.assertEqual(parent, "Securities and Deposits - _TC")
merge_account("Securities and Deposits - _TC", "Cash In Hand - _TC", doc.is_group, doc.root_type, doc.company)
parent = frappe.db.get_value("Account", "Earnest Money - _TC", "parent_account")
# Parent account of the child account changes after merging
self.assertEqual(parent, "Cash In Hand - _TC")
# Old account doesn't exist after merging
self.assertFalse(frappe.db.exists("Account", "Securities and Deposits - _TC"))
doc = frappe.get_doc("Account", "Current Assets - _TC")
# Raise error as is_group property doesn't match
self.assertRaises(frappe.ValidationError, merge_account, "Current Assets - _TC",\
"Accumulated Depreciation - _TC", doc.is_group, doc.root_type, doc.company)
doc = frappe.get_doc("Account", "Capital Stock - _TC")
# Raise error as root_type property doesn't match
self.assertRaises(frappe.ValidationError, merge_account, "Capital Stock - _TC",\
"Softwares - _TC", doc.is_group, doc.root_type, doc.company)
def _make_test_records(verbose):
from frappe.test_runner import make_test_objects

View File

@@ -27,13 +27,21 @@ class Budget(Document):
def validate_duplicate(self):
budget_against_field = frappe.scrub(self.budget_against)
budget_against = self.get(budget_against_field)
existing_budget = frappe.db.get_value("Budget", {budget_against_field: budget_against,
"fiscal_year": self.fiscal_year, "company": self.company,
"name": ["!=", self.name], "docstatus": ["!=", 2]})
if existing_budget:
frappe.throw(_("Another Budget record '{0}' already exists against {1} '{2}' for fiscal year {3}")
.format(existing_budget, self.budget_against, budget_against, self.fiscal_year), DuplicateBudgetError)
accounts = [d.account for d in self.accounts] or []
existing_budget = frappe.db.sql("""
select
b.name, ba.account from `tabBudget` b, `tabBudget Account` ba
where
ba.parent = b.name and b.docstatus < 2 and b.company = %s and %s=%s and
b.fiscal_year=%s and b.name != %sand ba.account in (%s) """
% ('%s', budget_against_field, '%s', '%s', '%s', ','.join(['%s'] * len(accounts))),
(self.company, budget_against, self.fiscal_year, self.name) + tuple(accounts), as_dict=1)
for d in existing_budget:
frappe.throw(_("Another Budget record '{0}' already exists against {1} '{2}' and account '{3}' for fiscal year {4}")
.format(d.name, self.budget_against, budget_against, d.account, self.fiscal_year), DuplicateBudgetError)
def validate_accounts(self):
account_list = []
for d in self.get('accounts'):

View File

@@ -27,22 +27,32 @@ def create_or_update_cheque_print_format(template_name):
doc = frappe.get_doc("Cheque Print Template", template_name)
cheque_print.html = """
<style>
.print-format {
padding: 0px;
}
@media screen {
.print-format {
padding: 0in;
}
}
</style>
<div style="position: relative; top:%(starting_position_from_top_edge)scm">
<div style="width:%(cheque_width)scm;height:%(cheque_height)scm;">
<span style="top: {{ %(acc_pay_dist_from_top_edge)s }}cm; left: {{ %(acc_pay_dist_from_left_edge)s }}cm;
border-bottom: solid 1px;border-top:solid 1px; position: absolute;">
<span style="top:%(acc_pay_dist_from_top_edge)scm; left:%(acc_pay_dist_from_left_edge)scm;
border-bottom: solid 1px;border-top:solid 1px; width:2cm;text-align: center; position: absolute;">
%(message_to_show)s
</span>
<span style="top:%(date_dist_from_top_edge)s cm; left:%(date_dist_from_left_edge)scm;
<span style="top:%(date_dist_from_top_edge)scm; left:%(date_dist_from_left_edge)scm;
position: absolute;">
{{ frappe.utils.formatdate(doc.reference_date) or '' }}
</span>
<span style="top:%(acc_no_dist_from_top_edge)scm;left:%(acc_no_dist_from_left_edge)scm;
position: absolute;">
position: absolute; min-width: 6cm;">
{{ doc.account_no or '' }}
</span>
<span style="top:%(payer_name_from_top_edge)scm;left: %(payer_name_from_left_edge)scm;
position: absolute;">
position: absolute; min-width: 6cm;">
{{doc.party_name}}
</span>
<span style="top:%(amt_in_words_from_top_edge)scm; left:%(amt_in_words_from_left_edge)scm;
@@ -51,11 +61,11 @@ def create_or_update_cheque_print_format(template_name):
{{frappe.utils.money_in_words(doc.base_paid_amount or doc.base_received_amount)}}
</span>
<span style="top:%(amt_in_figures_from_top_edge)scm;left: %(amt_in_figures_from_left_edge)scm;
position: absolute;">
position: absolute; min-width: 4cm;">
{{doc.get_formatted("base_paid_amount") or doc.get_formatted("base_received_amount")}}
</span>
<span style="top:%(signatory_from_top_edge)scm;left: %(signatory_from_left_edge)scm;
position: absolute;">
position: absolute; min-width: 6cm;">
{{doc.company}}
</span>
</div>

View File

@@ -132,7 +132,7 @@
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"search_index": 1,
"set_only_once": 0,
"unique": 0
},
@@ -702,7 +702,7 @@
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"search_index": 1,
"set_only_once": 0,
"unique": 0
}
@@ -718,7 +718,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-12-20 12:40:09.611951",
"modified": "2018-08-10 16:16:53.019380",
"modified_by": "Administrator",
"module": "Accounts",
"name": "GL Entry",
@@ -794,4 +794,4 @@
"sort_order": "DESC",
"track_changes": 0,
"track_seen": 0
}
}

View File

@@ -381,7 +381,7 @@
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"search_index": 1,
"set_only_once": 0,
"unique": 0
},
@@ -1443,7 +1443,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2017-08-31 11:21:09.442695",
"modified": "2018-08-10 16:35:31.361030",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Journal Entry",

View File

@@ -82,7 +82,7 @@ class JournalEntry(AccountsController):
d.reference_type = ''
d.reference_name = ''
d.db_update()
def unlink_asset_reference(self):
for d in self.get("accounts"):
if d.reference_type=="Asset" and d.reference_name:
@@ -125,7 +125,7 @@ class JournalEntry(AccountsController):
if (d.party_type == 'Customer' and flt(d.credit) > 0) or \
(d.party_type == 'Supplier' and flt(d.debit) > 0):
if d.is_advance=="No":
msgprint(_("Row {0}: Please check 'Is Advance' against Account {1} if this is an advance entry.").format(d.idx, d.account))
msgprint(_("Row {0}: Please check 'Is Advance' against Account {1} if this is an advance entry.").format(d.idx, d.account), alert=1)
elif d.reference_type in ("Sales Order", "Purchase Order") and d.is_advance != "Yes":
frappe.throw(_("Row {0}: Payment against Sales/Purchase Order should always be marked as advance").format(d.idx))

View File

@@ -199,7 +199,7 @@
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"search_index": 1,
"set_only_once": 0,
"unique": 0
},
@@ -661,7 +661,7 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -795,7 +795,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2017-12-07 19:54:19.851534",
"modified": "2018-08-10 16:35:42.833549",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Journal Entry Account",

View File

@@ -138,7 +138,8 @@ class OpeningInvoiceCreationTool(Document):
income_expense_account_field = "expense_account"
item = get_item_dict()
return frappe._dict({
args = frappe._dict({
"items": [item],
"is_opening": "Yes",
"set_posting_time": 1,
@@ -150,6 +151,11 @@ class OpeningInvoiceCreationTool(Document):
"currency": frappe.db.get_value("Company", self.company, "default_currency")
})
if self.invoice_type == "Sales":
args["is_pos"] = 0
return args
@frappe.whitelist()
def get_temporary_opening_account(company=None):
if not company:

View File

@@ -588,6 +588,10 @@ frappe.ui.form.on('Payment Entry', {
allocate_party_amount_against_ref_docs: function(frm, paid_amount) {
var total_positive_outstanding_including_order = 0;
var total_negative_outstanding = 0;
var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [],
function(d) { return flt(d.amount) }));
paid_amount -= total_deductions;
$.each(frm.doc.references || [], function(i, row) {
if(flt(row.outstanding_amount) > 0)
@@ -815,23 +819,30 @@ frappe.ui.form.on('Payment Entry Reference', {
reference_name: function(frm, cdt, cdn) {
var row = locals[cdt][cdn];
return frappe.call({
method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_reference_details",
args: {
reference_doctype: row.reference_doctype,
reference_name: row.reference_name,
party_account_currency: frm.doc.payment_type=="Receive" ?
frm.doc.paid_from_account_currency : frm.doc.paid_to_account_currency
},
callback: function(r, rt) {
if(r.message) {
$.each(r.message, function(field, value) {
frappe.model.set_value(cdt, cdn, field, value);
})
frm.refresh_fields();
if (row.reference_name && row.reference_doctype) {
return frappe.call({
method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_reference_details",
args: {
reference_doctype: row.reference_doctype,
reference_name: row.reference_name,
party_account_currency: frm.doc.payment_type=="Receive" ?
frm.doc.paid_from_account_currency : frm.doc.paid_to_account_currency
},
callback: function(r, rt) {
if(r.message) {
$.each(r.message, function(field, value) {
frappe.model.set_value(cdt, cdn, field, value);
})
let allocated_amount = frm.doc.unallocated_amount > row.outstanding_amount ?
row.outstanding_amount : frm.doc.unallocated_amount;
frappe.model.set_value(cdt, cdn, 'allocated_amount', allocated_amount);
frm.refresh_fields();
}
}
}
})
})
}
},
allocated_amount: function(frm) {

View File

@@ -40,7 +40,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -72,7 +71,6 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 1,
"translatable": 0,
"unique": 0
},
{
@@ -104,7 +102,6 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -134,7 +131,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -166,7 +162,6 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -198,7 +193,6 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -230,7 +224,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -262,7 +255,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -294,9 +286,8 @@
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"search_index": 1,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -329,7 +320,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -359,7 +349,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -392,7 +381,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -423,7 +411,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -455,7 +442,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -488,7 +474,6 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -521,7 +506,6 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -554,7 +538,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -584,7 +567,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -617,7 +599,6 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -650,7 +631,6 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -683,7 +663,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -716,7 +695,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -749,7 +727,6 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -781,7 +758,6 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -814,7 +790,6 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -844,7 +819,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -877,7 +851,6 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -909,7 +882,6 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -942,7 +914,6 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -975,7 +946,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1008,7 +978,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1041,7 +1010,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1073,7 +1041,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1105,7 +1072,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1138,7 +1104,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1169,7 +1134,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1199,7 +1163,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1231,7 +1194,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1264,7 +1226,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1296,7 +1257,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1329,7 +1289,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1361,7 +1320,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1392,7 +1350,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1424,7 +1381,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1454,7 +1410,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1484,9 +1439,8 @@
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"search_index": 1,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1518,7 +1472,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1551,7 +1504,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1584,7 +1536,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1604,7 +1555,7 @@
"in_standard_filter": 0,
"label": "Remarks",
"length": 0,
"no_copy": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -1615,7 +1566,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1645,7 +1595,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1677,7 +1626,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1709,7 +1657,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1740,7 +1687,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1772,7 +1718,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1803,7 +1748,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -1834,7 +1778,6 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}
],
@@ -1848,7 +1791,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-02-19 16:58:23.899015",
"modified": "2018-08-10 16:34:46.771275",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry",

View File

@@ -337,14 +337,15 @@ class PaymentEntry(AccountsController):
total_negative_outstanding = sum([abs(flt(d.outstanding_amount))
for d in self.get("references") if flt(d.outstanding_amount) < 0])
party_amount = self.paid_amount if self.payment_type=="Receive" else self.received_amount
paid_amount = self.paid_amount if self.payment_type=="Receive" else self.received_amount
additional_charges = sum([flt(d.amount) for d in self.deductions])
if not total_negative_outstanding:
frappe.throw(_("Cannot {0} {1} {2} without any negative outstanding invoice")
.format(self.payment_type, ("to" if self.party_type=="Customer" else "from"),
self.party_type), InvalidPaymentEntry)
elif party_amount > total_negative_outstanding:
elif paid_amount - additional_charges > total_negative_outstanding:
frappe.throw(_("Paid Amount cannot be greater than total negative outstanding amount {0}")
.format(total_negative_outstanding), InvalidPaymentEntry)
@@ -724,8 +725,11 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
exchange_rate = ref_doc.get("conversion_rate") or \
get_exchange_rate(party_account_currency, company_currency, ref_doc.posting_date)
if reference_doctype in ("Sales Invoice", "Purchase Invoice", "Expense Claim"):
if reference_doctype in ("Sales Invoice", "Purchase Invoice"):
outstanding_amount = ref_doc.get("outstanding_amount")
elif reference_doctype == "Expense Claim":
outstanding_amount = flt(ref_doc.get("total_sanctioned_amount")) \
- flt(ref_doc.get("total_amount+reimbursed")) - flt(ref_doc.get("total_advance_amount"))
elif reference_doctype == "Employee Advance":
outstanding_amount = ref_doc.advance_amount - flt(ref_doc.paid_amount)
else:

View File

@@ -111,8 +111,8 @@ def apply_pricing_rule(args):
item_list = args.get("items")
args.pop("items")
set_serial_nos_based_on_fifo = frappe.db.get_single_value("Stock Settings",
set_serial_nos_based_on_fifo = frappe.db.get_single_value("Stock Settings",
"automatically_set_serial_nos_based_on_fifo")
for item in item_list:
@@ -122,7 +122,7 @@ def apply_pricing_rule(args):
if set_serial_nos_based_on_fifo and not args.get('is_return'):
out.append(get_serial_no_for_item(args_copy))
return out
def get_serial_no_for_item(args):
from erpnext.stock.get_item_details import get_serial_no
@@ -143,7 +143,7 @@ def get_pricing_rule_for_item(args):
"name": args.name,
"pricing_rule": None
})
if args.ignore_pricing_rule or not args.item_code:
if frappe.db.exists(args.doctype, args.name) and args.get("pricing_rule"):
item_details = remove_pricing_rule_for_item(args.get("pricing_rule"), item_details)
@@ -180,7 +180,7 @@ def get_pricing_rule_for_item(args):
item_details.margin_rate_or_amount = pricing_rule.margin_rate_or_amount
if pricing_rule.price_or_discount == "Price":
item_details.update({
"price_list_rate": (pricing_rule.price/flt(args.conversion_rate)) * args.conversion_factor or 1.0 \
"price_list_rate": (pricing_rule.price/flt(args.conversion_rate)) * (args.conversion_factor or 1.0) \
if args.conversion_rate else 0.0,
"discount_percentage": 0.0
})
@@ -192,7 +192,7 @@ def get_pricing_rule_for_item(args):
return item_details
def remove_pricing_rule_for_item(pricing_rule, item_details):
pricing_rule = frappe.db.get_value('Pricing Rule', pricing_rule,
pricing_rule = frappe.db.get_value('Pricing Rule', pricing_rule,
['price_or_discount', 'margin_type'], as_dict=1)
if pricing_rule and pricing_rule.price_or_discount == 'Discount Percentage':
item_details.discount_percentage = 0.0
@@ -209,14 +209,14 @@ def remove_pricing_rule_for_item(pricing_rule, item_details):
def remove_pricing_rules(item_list):
if isinstance(item_list, basestring):
item_list = json.loads(item_list)
out = []
out = []
for item in item_list:
item = frappe._dict(item)
out.append(remove_pricing_rule_for_item(item.get("pricing_rule"), item))
return out
def get_pricing_rules(args):
def _get_tree_conditions(parenttype, allow_blank=True):
field = frappe.scrub(parenttype)

View File

@@ -21,8 +21,6 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
if(!this.frm.doc.supplier && this.frm.doc.credit_to) {
this.frm.set_df_property("credit_to", "print_hide", 0);
}
} else {
this.frm.set_value("disable_rounded_total", cint(frappe.sys_defaults.disable_rounded_total));
}
},

View File

@@ -1239,7 +1239,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_bulk_edit": 1,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -3410,6 +3410,65 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "group_same_items",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Group same items",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_112",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "select_print_heading",
"fieldtype": "Link",
"hidden": 0,
@@ -3914,7 +3973,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2017-12-20 17:49:51.230092",
"modified": "2018-07-06 02:38:40.310899",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice",

View File

@@ -363,7 +363,10 @@ class PurchaseInvoice(BuyingController):
return gl_entries
def make_supplier_gl_entry(self, gl_entries):
grand_total = self.rounded_total or self.grand_total
# Checked both rounding_adjustment and rounded_total
# because rounded_total had value even before introcution of posting GLE based on rounded total
grand_total = self.rounded_total if (self.rounding_adjustment and self.rounded_total) else self.grand_total
if grand_total:
# Didnot use base_grand_total to book rounding loss gle
grand_total_in_company_currency = flt(grand_total * self.conversion_rate,
@@ -388,16 +391,20 @@ class PurchaseInvoice(BuyingController):
expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
warehouse_account = get_warehouse_account_map()
voucher_wise_stock_value = {}
if self.update_stock:
for d in frappe.get_all('Stock Ledger Entry',
fields = ["voucher_detail_no", "stock_value_difference"], filters={'voucher_no': self.name}):
voucher_wise_stock_value.setdefault(d.voucher_detail_no, d.stock_value_difference)
for item in self.get("items"):
if flt(item.base_net_amount):
account_currency = get_account_currency(item.expense_account)
if self.update_stock and self.auto_accounting_for_stock and item.item_code in stock_items:
val_rate_db_precision = 6 if cint(item.precision("valuation_rate")) <= 6 else 9
# warehouse account
warehouse_debit_amount = flt(flt(item.valuation_rate, val_rate_db_precision)
* flt(item.qty) * flt(item.conversion_factor), item.precision("base_net_amount"))
warehouse_debit_amount = self.make_stock_adjustment_entry(gl_entries,
item, voucher_wise_stock_value, account_currency)
gl_entries.append(
self.get_gl_dict({
@@ -469,6 +476,36 @@ class PurchaseInvoice(BuyingController):
self.negative_expense_to_be_booked += flt(item.item_tax_amount, \
item.precision("item_tax_amount"))
def make_stock_adjustment_entry(self, gl_entries, item, voucher_wise_stock_value, account_currency):
net_amt_precision = item.precision("base_net_amount")
val_rate_db_precision = 6 if cint(item.precision("valuation_rate")) <= 6 else 9
warehouse_debit_amount = flt(flt(item.valuation_rate, val_rate_db_precision)
* flt(item.qty) * flt(item.conversion_factor), net_amt_precision)
# Stock ledger value is not matching with the warehouse amount
if (self.update_stock and voucher_wise_stock_value.get(item.name) and
warehouse_debit_amount != flt(voucher_wise_stock_value.get(item.name), net_amt_precision)):
cost_of_goods_sold_account = self.get_company_default("default_expense_account")
stock_amount = flt(voucher_wise_stock_value.get(item.name), net_amt_precision)
stock_adjustment_amt = warehouse_debit_amount - stock_amount
gl_entries.append(
self.get_gl_dict({
"account": cost_of_goods_sold_account,
"against": item.expense_account,
"debit": stock_adjustment_amt,
"remarks": self.get("remarks") or _("Stock Adjustment"),
"cost_center": item.cost_center,
"project": item.project
}, account_currency)
)
warehouse_debit_amount = stock_amount
return warehouse_debit_amount
def make_tax_gl_entries(self, gl_entries):
# tax table gl entries
valuation_tax = {}

View File

@@ -585,6 +585,38 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "discount_percentage",
"fieldname": "discount_amount",
"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": "Discount Amount",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -2156,7 +2188,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2017-11-30 14:21:00.962126",
"modified": "2018-08-06 05:17:38.205356",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice Item",

View File

@@ -506,6 +506,7 @@ def save_invoice(doc, name, name_list):
frappe.db.commit()
name_list.append(name)
except Exception:
frappe.db.rollback()
frappe.log_error(frappe.get_traceback())
return name_list

View File

@@ -319,6 +319,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
},
pos_profile: function() {
this.frm.doc.taxes = []
this.set_pos_data();
},

View File

@@ -639,6 +639,66 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_21",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval: doc.is_return && doc.return_against",
"fieldname": "update_billed_amount_in_sales_order",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Update Billed Amount in Sales Order",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -1459,7 +1519,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_bulk_edit": 1,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -3742,12 +3802,12 @@
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "language",
"fieldtype": "Data",
"fieldname": "group_same_items",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -3755,14 +3815,14 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Print Language",
"label": "Group same items",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
@@ -3831,6 +3891,36 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "language",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Print Language",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -4683,7 +4773,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2018-03-16 15:19:54.711885",
"modified": "2018-07-17 13:46:52.449142",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",
@@ -4774,7 +4864,7 @@
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 1,
"search_fields": "posting_date, due_date, customer, base_grand_total, outstanding_amount",
"search_fields": "posting_date,due_date,customer,base_grand_total,outstanding_amount",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",

View File

@@ -116,7 +116,7 @@ class SalesInvoice(SellingController):
self.check_prev_docstatus()
if self.is_return:
if self.is_return and not self.update_billed_amount_in_sales_order:
# NOTE status updating bypassed for is_return
self.status_updater = []
@@ -161,7 +161,7 @@ class SalesInvoice(SellingController):
if frappe.db.get_single_value('Accounts Settings', 'unlink_payment_on_cancellation_of_invoice'):
unlink_ref_doc_from_payment_entries(self)
if self.is_return:
if self.is_return and not self.update_billed_amount_in_sales_order:
# NOTE status updating bypassed for is_return
self.status_updater = []
@@ -318,6 +318,7 @@ class SalesInvoice(SellingController):
if not for_validate and not self.customer:
self.customer = pos.customer
self.ignore_pricing_rule = pos.ignore_pricing_rule
if pos.get('account_for_change_amount'):
self.account_for_change_amount = pos.get('account_for_change_amount')
@@ -334,7 +335,7 @@ class SalesInvoice(SellingController):
for item in self.get("items"):
if item.get('item_code'):
for fname, val in get_pos_profile_item_details(pos,
frappe._dict(item.as_dict()), pos).items():
frappe._dict(item.as_dict()), pos, True).items():
if (not for_validate) or (for_validate and not item.get(fname)):
item.set(fname, val)
@@ -640,7 +641,9 @@ class SalesInvoice(SellingController):
return gl_entries
def make_customer_gl_entry(self, gl_entries):
grand_total = self.rounded_total or self.grand_total
# Checked both rounding_adjustment and rounded_total
# because rounded_total had value even before introcution of posting GLE based on rounded total
grand_total = self.rounded_total if (self.rounding_adjustment and self.rounded_total) else self.grand_total
if grand_total:
# Didnot use base_grand_total to book rounding loss gle
grand_total_in_company_currency = flt(grand_total * self.conversion_rate,
@@ -668,9 +671,11 @@ class SalesInvoice(SellingController):
self.get_gl_dict({
"account": tax.account_head,
"against": self.customer,
"credit": flt(tax.base_tax_amount_after_discount_amount),
"credit_in_account_currency": flt(tax.base_tax_amount_after_discount_amount) \
if account_currency==self.company_currency else flt(tax.tax_amount_after_discount_amount),
"credit": flt(tax.base_tax_amount_after_discount_amount,
tax.precision("tax_amount_after_discount_amount")),
"credit_in_account_currency": (flt(tax.base_tax_amount_after_discount_amount,
tax.precision("base_tax_amount_after_discount_amount")) if account_currency==self.company_currency else
flt(tax.tax_amount_after_discount_amount, tax.precision("tax_amount_after_discount_amount"))),
"cost_center": tax.cost_center
}, account_currency)
)
@@ -678,7 +683,7 @@ class SalesInvoice(SellingController):
def make_item_gl_entries(self, gl_entries):
# income account gl entries
for item in self.get("items"):
if flt(item.base_net_amount):
if flt(item.base_net_amount, item.precision("base_net_amount")):
if item.is_fixed_asset:
asset = frappe.get_doc("Asset", item.asset)
@@ -695,9 +700,10 @@ class SalesInvoice(SellingController):
self.get_gl_dict({
"account": item.income_account,
"against": self.customer,
"credit": item.base_net_amount,
"credit_in_account_currency": item.base_net_amount \
if account_currency==self.company_currency else item.net_amount,
"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"))
if account_currency==self.company_currency
else flt(item.net_amount, item.precision("net_amount"))),
"cost_center": item.cost_center
}, account_currency)
)
@@ -768,7 +774,7 @@ class SalesInvoice(SellingController):
def make_write_off_gl_entry(self, gl_entries):
# write off entries, applicable if only pos
if self.write_off_account and self.write_off_amount:
if self.write_off_account and flt(self.write_off_amount, self.precision("write_off_amount")):
write_off_account_currency = get_account_currency(self.write_off_account)
default_cost_center = frappe.db.get_value('Company', self.company, 'cost_center')
@@ -778,9 +784,10 @@ class SalesInvoice(SellingController):
"party_type": "Customer",
"party": self.customer,
"against": self.write_off_account,
"credit": self.base_write_off_amount,
"credit_in_account_currency": self.base_write_off_amount \
if self.party_account_currency==self.company_currency else self.write_off_amount,
"credit": flt(self.base_write_off_amount, self.precision("base_write_off_amount")),
"credit_in_account_currency": (flt(self.base_write_off_amount,
self.precision("base_write_off_amount")) if self.party_account_currency==self.company_currency
else flt(self.write_off_amount, self.precision("write_off_amount"))),
"against_voucher": self.return_against if cint(self.is_return) else self.name,
"against_voucher_type": self.doctype
}, self.party_account_currency)
@@ -789,15 +796,16 @@ class SalesInvoice(SellingController):
self.get_gl_dict({
"account": self.write_off_account,
"against": self.customer,
"debit": self.base_write_off_amount,
"debit_in_account_currency": self.base_write_off_amount \
if write_off_account_currency==self.company_currency else self.write_off_amount,
"debit": flt(self.base_write_off_amount, self.precision("base_write_off_amount")),
"debit_in_account_currency": (flt(self.base_write_off_amount,
self.precision("base_write_off_amount")) if write_off_account_currency==self.company_currency
else flt(self.write_off_amount, self.precision("write_off_amount"))),
"cost_center": self.write_off_cost_center or default_cost_center
}, write_off_account_currency)
)
def make_gle_for_rounding_adjustment(self, gl_entries):
if self.rounding_adjustment:
if flt(self.rounding_adjustment, self.precision("rounding_adjustment")):
round_off_account, round_off_cost_center = \
get_round_off_account_and_cost_center(self.company)
@@ -805,8 +813,10 @@ class SalesInvoice(SellingController):
self.get_gl_dict({
"account": round_off_account,
"against": self.customer,
"credit_in_account_currency": self.rounding_adjustment,
"credit": self.base_rounding_adjustment,
"credit_in_account_currency": flt(self.rounding_adjustment,
self.precision("rounding_adjustment")),
"credit": flt(self.base_rounding_adjustment,
self.precision("base_rounding_adjustment")),
"cost_center": round_off_cost_center,
}
))

View File

@@ -39,18 +39,20 @@ frappe.ui.form.on("Tax Rule", "customer", function(frm) {
});
frappe.ui.form.on("Tax Rule", "supplier", function(frm) {
frappe.call({
method:"erpnext.accounts.doctype.tax_rule.tax_rule.get_party_details",
args: {
"party": frm.doc.supplier,
"party_type": "supplier"
},
callback: function(r) {
if(!r.exc) {
$.each(r.message, function(k, v) {
frm.set_value(k, v);
});
if(frm.doc.supplier) {
frappe.call({
method:"erpnext.accounts.doctype.tax_rule.tax_rule.get_party_details",
args: {
"party": frm.doc.supplier,
"party_type": "supplier"
},
callback: function(r) {
if(!r.exc) {
$.each(r.message, function(k, v) {
frm.set_value(k, v);
});
}
}
}
});
});
}
});

View File

@@ -20,8 +20,8 @@ from erpnext import get_default_currency, get_company_currency
class DuplicatePartyAccountError(frappe.ValidationError): pass
@frappe.whitelist()
def get_party_details(party=None, account=None, party_type="Customer", company=None,
posting_date=None, price_list=None, currency=None, doctype=None, ignore_permissions=False):
def get_party_details(party=None, account=None, party_type="Customer", company=None, posting_date=None,
price_list=None, currency=None, doctype=None, ignore_permissions=False, fetch_payment_terms_template=True):
if not party:
return {}
@@ -30,10 +30,10 @@ def get_party_details(party=None, account=None, party_type="Customer", company=N
frappe.throw(_("{0}: {1} does not exists").format(party_type, party))
return _get_party_details(party, account, party_type,
company, posting_date, price_list, currency, doctype, ignore_permissions)
company, posting_date, price_list, currency, doctype, ignore_permissions, fetch_payment_terms_template)
def _get_party_details(party=None, account=None, party_type="Customer", company=None,
posting_date=None, price_list=None, currency=None, doctype=None, ignore_permissions=False):
def _get_party_details(party=None, account=None, party_type="Customer", company=None, posting_date=None,
price_list=None, currency=None, doctype=None, ignore_permissions=False, fetch_payment_terms_template=True):
out = frappe._dict(set_account_and_due_date(party, account, party_type, company, posting_date, doctype))
@@ -50,7 +50,9 @@ def _get_party_details(party=None, account=None, party_type="Customer", company=
set_other_values(out, party, party_type)
set_price_list(out, party, party_type, price_list)
out["taxes_and_charges"] = set_taxes(party.name, party_type, posting_date, company, out.customer_group, out.supplier_type)
out["payment_terms_template"] = get_pyt_term_template(party.name, party_type, company)
if fetch_payment_terms_template:
out["payment_terms_template"] = get_pyt_term_template(party.name, party_type, company)
if not out.get("currency"):
out["currency"] = currency
@@ -272,6 +274,7 @@ def get_due_date(posting_date, party_type, party, company=None):
if posting_date and party:
due_date = posting_date
template_name = get_pyt_term_template(party, party_type, company)
if template_name:
due_date = get_due_date_from_template(template_name, posting_date).strftime("%Y-%m-%d")
else:
@@ -304,11 +307,13 @@ def get_due_date_from_template(template_name, posting_date):
return due_date
def validate_due_date(posting_date, due_date, party_type, party, company=None):
def validate_due_date(posting_date, due_date, party_type, party, company=None, template_name=None):
if getdate(due_date) < getdate(posting_date):
frappe.throw(_("Due Date cannot be before Posting Date"))
else:
default_due_date = get_due_date(posting_date, party_type, party, company)
if not template_name: return
default_due_date = get_due_date_from_template(template_name, posting_date).strftime("%Y-%m-%d")
if not default_due_date:
return
@@ -404,10 +409,21 @@ def get_timeline_data(doctype, name):
from frappe.desk.form.load import get_communication_data
out = {}
fields = 'date(creation), count(name)'
after = add_years(None, -1).strftime('%Y-%m-%d')
group_by='group by date(creation)'
data = get_communication_data(doctype, name,
fields = 'date(creation), count(name)',
after = add_years(None, -1).strftime('%Y-%m-%d'),
group_by='group by date(creation)', as_dict=False)
fields=fields, after=after, group_by=group_by, as_dict=False)
# fetch and append data from Activity Log
data += frappe.db.sql("""select {fields}
from `tabActivity Log`
where reference_doctype="{doctype}" and reference_name="{name}"
and status!='Success' and creation > {after}
{group_by} order by creation desc
""".format(doctype=frappe.db.escape(doctype), name=frappe.db.escape(name), fields=fields,
group_by=group_by, after=after), as_dict=False)
timeline_items = dict(data)

View File

@@ -32,7 +32,7 @@ frappe.query_reports["Accounts Payable"] = {
"fieldname":"ageing_based_on",
"label": __("Ageing Based On"),
"fieldtype": "Select",
"options": 'Posting Date\nDue Date',
"options": 'Posting Date\nDue Date\nSupplier Invoice Date',
"default": "Posting Date"
},
{

View File

@@ -19,7 +19,13 @@
<h2 class="text-center">{%= __(report.report_name) %}</h2>
<h4 class="text-center">{%= filters.customer || filters.supplier %} </h4>
<h4 class="text-center">
{% if (filters.customer_name) { %}
{%= filters.customer_name %}
{% } else { %}
{%= filters.customer || filters.supplier %}
{% } %}
</h4>
<h6 class="text-center">
{% if (filters.tax_id) { %}
{%= __("Tax Id: ")%} {%= filters.tax_id %}
@@ -69,7 +75,7 @@
<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(flt(balance_row[__("Outstanding Amount")]), data[data.length-1]["currency"]) %}
{%= format_currency(flt(balance_row[("outstanding_amount")]), data[data.length-1]["currency"]) %}
</td>
</tr>
<td>{%= __("PDC/LC") %}</td>
@@ -78,7 +84,7 @@
<td></td>
<td></td>
<td class="text-right">
{%= format_currency(flt(balance_row[__("PDC/LC Amount")]), data[data.length-1]["currency"]) %}
{%= format_currency(flt(balance_row[("pdc/lc_amount")]), data[data.length-1]["currency"]) %}
</td>
<tr class="cvs-footer">
<th class="text-left">{%= __("Cheques Required") %}</th>
@@ -87,7 +93,7 @@
<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>
{%= format_currency(flt(balance_row[("outstanding_amount")]-balance_row[("pdc/lc_amount")]), data[data.length-1]["currency"]) %}</th>
</tr>
</tbody>
@@ -155,26 +161,26 @@
</td>
{% } %}
<td style="text-align: right">
{%= format_currency(data[i]["Invoiced Amount"], data[i]["currency"]) %}</td>
{%= format_currency(data[i]["invoiced_amount"], data[i]["currency"]) %}</td>
{% if(!filters.show_pdc_in_print) { %}
<td style="text-align: right">
{%= format_currency(data[i]["Paid Amount"], data[i]["currency"]) %}</td>
{%= format_currency(data[i]["paid_amount"], data[i]["currency"]) %}</td>
<td style="text-align: right">
{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["Credit Note"], data[i]["currency"]) : format_currency(data[i]["Debit Note"], data[i]["currency"]) %}</td>
{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["credit_note"], data[i]["currency"]) : format_currency(data[i]["debit_note"], data[i]["currency"]) %}</td>
{% } %}
<td style="text-align: right">
{%= format_currency(data[i]["Outstanding Amount"], data[i]["currency"]) %}</td>
{%= format_currency(data[i]["outstanding_amount"], data[i]["currency"]) %}</td>
{% if(filters.show_pdc_in_print) { %}
{% if(report.report_name === "Accounts Receivable") { %}
<td style="text-align: right">
{%= data[i][__("Customer LPO")] %}</td>
{%= data[i]["po_no"] %}</td>
{% } %}
<td style="text-align: right">{%= frappe.datetime.str_to_user(data[i][__("PDC/LC Date")]) %}</td>
<td style="text-align: right">{%= data[i][__("PDC/LC Ref")] %}</td>
<td style="text-align: right">{%= format_currency(data[i][__("PDC/LC Amount")], data[i]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i][__("Remaining Balance")], data[i]["currency"]) %}</td>
<td style="text-align: right">{%= frappe.datetime.str_to_user(data[i][("pdc/lc_date")]) %}</td>
<td style="text-align: right">{%= data[i][("pdc/lc_ref")] %}</td>
<td style="text-align: right">{%= format_currency(data[i][("pdc/lc_amount")], data[i]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i][("remaining_balance")], data[i]["currency"]) %}</td>
{% } %}
{% } else { %}
<td></td>
@@ -183,15 +189,15 @@
{% } %}
<td><b>{%= __("Total") %}</b></td>
<td style="text-align: right">
{%= format_currency(data[i]["Invoiced Amount"], data[i]["currency"] ) %}</td>
{%= format_currency(data[i]["invoiced_amount"], data[i]["currency"] ) %}</td>
{% if(!filters.show_pdc_in_print) { %}
<td style="text-align: right">
{%= format_currency(data[i]["Paid Amount"], data[i]["currency"]) %}</td>
<td style="text-align: right">{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["Credit Note"], data[i]["currency"]) : format_currency(data[i]["Debit Note"], data[i]["currency"]) %} </td>
{%= format_currency(data[i]["paid_amount"], data[i]["currency"]) %}</td>
<td style="text-align: right">{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["credit_note"], data[i]["currency"]) : format_currency(data[i]["Debit Note"], data[i]["currency"]) %} </td>
{% } %}
<td style="text-align: right">
{%= format_currency(data[i]["Outstanding Amount"], data[i]["currency"]) %}</td>
{%= format_currency(data[i]["outstanding_amount"], data[i]["currency"]) %}</td>
{% if(filters.show_pdc_in_print) { %}
{% if(report.report_name === "Accounts Receivable") { %}
@@ -199,9 +205,9 @@
{%= data[i][__("Customer LPO")] %}</td>
{% } %}
<td style="text-align: right">{%= frappe.datetime.str_to_user(data[i][__("PDC/LC Date")]) %}</td>
<td style="text-align: right">{%= data[i][__("PDC/LC Ref")] %}</td>
<td style="text-align: right">{%= format_currency(data[i][__("PDC/LC Amount")], data[i]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i][__("Remaining Balance")], data[i]["currency"]) %}</td>
<td style="text-align: right">{%= data[i][("pdc/lc_ref")] %}</td>
<td style="text-align: right">{%= format_currency(data[i][("pdc/lc_amount")], data[i]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i][("remaining_balance")], data[i]["currency"]) %}</td>
{% } %}
{% } %}
{% } else { %}
@@ -222,14 +228,14 @@
{% } else { %}
<td><b>{%= __("Total") %}</b></td>
{% } %}
<td style="text-align: right">{%= format_currency(data[i][__("Total Invoiced Amt")], data[i]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i][__("Total Paid Amt")], data[i]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i][("total_invoiced_amt")], data[i]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i][("total_paid_amt")], data[i]["currency"]) %}</td>
<td style="text-align: right">{%= report.report_name === "Accounts Receivable Summary" ? format_currency(data[i][__("Credit Note Amt")], data[i]["currency"]) : format_currency(data[i][__("Debit Note Amt")], data[i]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i][__("Total Outstanding Amt")], data[i]["currency"]) %}</td>
<td style="text-align: right">{%= format_currency(data[i][("total_outstanding_amt")], data[i]["currency"]) %}</td>
{% } %}
{% } %}
</tr>
{% } %}
</tbody>
</table>
<p class="text-right text-muted">{{ __("Printed On ") }}{%= dateutil.str_to_user(dateutil.get_datetime_as_string()) %}</p>
<p class="text-right text-muted">{{ __("Printed On ") }}{%= dateutil.str_to_user(dateutil.get_datetime_as_string()) %}</p>

View File

@@ -17,8 +17,9 @@ frappe.query_reports["Accounts Receivable"] = {
"options": "Customer",
on_change: () => {
var customer = frappe.query_report_filters_by_name.customer.get_value();
frappe.db.get_value('Customer', customer, "tax_id", function(value) {
frappe.db.get_value('Customer', customer, ["tax_id", "customer_name"], function(value) {
frappe.query_report_filters_by_name.tax_id.set_value(value["tax_id"]);
frappe.query_report_filters_by_name.customer_name.set_value(value["customer_name"]);
});
}
},
@@ -81,6 +82,12 @@ frappe.query_reports["Accounts Receivable"] = {
"label": __("Tax Id"),
"fieldtype": "Data",
"hidden": 1
},
{
"fieldname":"customer_name",
"label": __("Customer Name"),
"fieldtype": "Data",
"hidden": 1
}
],

View File

@@ -60,6 +60,7 @@ class ReceivablePayableReport(object):
for label in ("Invoiced Amount", "Paid Amount", credit_or_debit_note, "Outstanding Amount"):
columns.append({
"label": label,
"fieldname": frappe.scrub(label),
"fieldtype": "Currency",
"options": "currency",
"width": 120
@@ -87,25 +88,49 @@ class ReceivablePayableReport(object):
"width": 120
})
columns.append({
columns += [
{
"fieldname": "currency",
"label": _("Currency"),
"fieldtype": "Link",
"options": "Currency",
"width": 100
})
columns += [
_("PDC/LC Date") + ":Date:110",
_("PDC/LC Ref") + ":Data:110",
_("PDC/LC Amount") + ":Currency/currency:130",
_("Remaining Balance") + ":Currency/currency:130"
]
},
{
"fieldname": "pdc/lc_date",
"label": _("PDC/LC Date"),
"fieldtype": "Date",
"width": 110
},
{
"fieldname": "pdc/lc_ref",
"label": _("PDC/LC Ref"),
"fieldtype": "Data",
"width": 110
},
{
"fieldname": "pdc/lc_amount",
"label": _("PDC/LC Amount"),
"fieldtype": "Currency",
"options": "Currency",
"width": 130
},
{
"fieldname": "remaining_balance",
"label": _("Remaining Balance"),
"fieldtype": "Currency",
"options": "Currency",
"width": 130
}]
if args.get('party_type') == 'Customer':
columns += [_("Customer LPO") + ":Data:100"]
columns.append({
"label": _("Customer LPO"),
"fieldtype": "Data",
"fieldname": "po_no",
"width": 100,
})
columns += [_("Delivery Note") + ":Data:100"]
if args.get("party_type") == "Customer":
columns += [
_("Territory") + ":Link/Territory:80",
@@ -123,9 +148,6 @@ class ReceivablePayableReport(object):
currency_precision = get_currency_precision() or 2
dr_or_cr = "debit" if args.get("party_type") == "Customer" else "credit"
dn_details = get_dn_details(args.get("party_type"))
voucher_details = self.get_voucher_details(args.get("party_type"), dn_details)
future_vouchers = self.get_entries_after(self.filters.report_date, args.get("party_type"))
if not self.filters.get("company"):
@@ -137,8 +159,14 @@ class ReceivablePayableReport(object):
data = []
pdc_details = get_pdc_details(args.get("party_type"), self.filters.report_date)
gl_entries_data = self.get_entries_till(self.filters.report_date, args.get("party_type"))
for gle in self.get_entries_till(self.filters.report_date, args.get("party_type")):
if gl_entries_data:
voucher_nos = [d.voucher_no for d in gl_entries_data] or []
dn_details = get_dn_details(args.get("party_type"), voucher_nos)
voucher_details = get_voucher_details(args.get("party_type"), voucher_nos, dn_details)
for gle in gl_entries_data:
if self.is_receivable_or_payable(gle, dr_or_cr, future_vouchers):
outstanding_amount, credit_note_amount = self.get_outstanding_amount(gle,
self.filters.report_date, dr_or_cr, return_entries, currency_precision)
@@ -151,6 +179,7 @@ class ReceivablePayableReport(object):
# get due date
due_date = voucher_details.get(gle.voucher_no, {}).get("due_date", "")
bill_date = voucher_details.get(gle.voucher_no, {}).get("bill_date", "")
row += [gle.voucher_type, gle.voucher_no, due_date]
@@ -167,15 +196,25 @@ class ReceivablePayableReport(object):
row += [invoiced_amount, paid_amt, credit_note_amount, outstanding_amount]
# ageing data
entry_date = due_date if self.filters.ageing_based_on == "Due Date" else gle.posting_date
if self.filters.ageing_based_on == "Due Date":
entry_date = due_date
elif self.filters.ageing_based_on == "Supplier Invoice Date":
entry_date = bill_date
else:
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)
# 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
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
if self.filters.get(scrub(args.get("party_type"))):
row.append(gle.account_currency)
else:
@@ -207,12 +246,11 @@ class ReceivablePayableReport(object):
def get_entries_after(self, report_date, party_type):
# returns a distinct list
return list(set([(e.voucher_type, e.voucher_no) for e in self.get_gl_entries(party_type)
if getdate(e.posting_date) > report_date]))
return list(set([(e.voucher_type, e.voucher_no) for e in self.get_gl_entries(party_type, report_date, for_future=True)]))
def get_entries_till(self, report_date, party_type):
# returns a generator
return (e for e in self.get_gl_entries(party_type) if getdate(e.posting_date) <= report_date)
return self.get_gl_entries(party_type, report_date)
def is_receivable_or_payable(self, gle, dr_or_cr, future_vouchers):
return (
@@ -239,14 +277,16 @@ class ReceivablePayableReport(object):
for e in self.get_gl_entries_for(gle.party, gle.party_type, gle.voucher_type, gle.voucher_no):
if getdate(e.posting_date) <= report_date and e.name!=gle.name:
amount = flt(e.get(reverse_dr_or_cr)) - flt(e.get(dr_or_cr))
amount = flt(e.get(reverse_dr_or_cr), currency_precision) - flt(e.get(dr_or_cr), currency_precision)
if e.voucher_no not in return_entries:
payment_amount += amount
else:
credit_note_amount += amount
outstanding_amount = flt((flt(gle.get(dr_or_cr)) - flt(gle.get(reverse_dr_or_cr)) \
- payment_amount - credit_note_amount), currency_precision)
outstanding_amount = (flt((flt(gle.get(dr_or_cr), currency_precision)
- flt(gle.get(reverse_dr_or_cr), currency_precision)
- payment_amount - credit_note_amount), currency_precision))
credit_note_amount = flt(credit_note_amount, currency_precision)
return outstanding_amount, credit_note_amount
@@ -275,39 +315,31 @@ class ReceivablePayableReport(object):
return self.party_map
def get_voucher_details(self, party_type, dn_details):
voucher_details = frappe._dict()
def get_gl_entries(self, party_type, date=None, for_future=False):
conditions, values = self.prepare_conditions(party_type)
if party_type == "Customer":
for si in frappe.db.sql("""select name, due_date, po_no
from `tabSales Invoice` where docstatus=1""", as_dict=1):
si['delivery_note'] = dn_details.get(si.name)
voucher_details.setdefault(si.name, si)
if self.filters.get(scrub(party_type)):
select_fields = "sum(debit_in_account_currency) as debit, sum(credit_in_account_currency) as credit"
else:
select_fields = "sum(debit) as debit, sum(credit) as credit"
if party_type == "Supplier":
for pi in frappe.db.sql("""select name, due_date, bill_no, bill_date
from `tabPurchase Invoice` where docstatus=1""", as_dict=1):
voucher_details.setdefault(pi.name, pi)
if date and not for_future:
conditions += " and posting_date <= '%s'" % date
return voucher_details
if date and for_future:
conditions += " and posting_date > '%s'" % date
def get_gl_entries(self, party_type):
if not hasattr(self, "gl_entries"):
conditions, values = self.prepare_conditions(party_type)
if self.filters.get(scrub(party_type)):
select_fields = "sum(debit_in_account_currency) as debit, sum(credit_in_account_currency) as credit"
else:
select_fields = "sum(debit) as debit, sum(credit) as credit"
self.gl_entries = frappe.db.sql("""select name, posting_date, account, party_type, party,
voucher_type, voucher_no, against_voucher_type, against_voucher,
account_currency, remarks, {0}
from `tabGL Entry`
where docstatus < 2 and party_type=%s and (party is not null and party != '') {1}
self.gl_entries = frappe.db.sql("""
select
name, posting_date, account, party_type, party, voucher_type, voucher_no,
against_voucher_type, against_voucher, account_currency, remarks, {0}
from
`tabGL Entry`
where
docstatus < 2 and party_type=%s and (party is not null and party != '') {1}
group by voucher_type, voucher_no, against_voucher_type, against_voucher, party
order by posting_date, party"""
.format(select_fields, conditions), values, as_dict=True)
.format(select_fields, conditions), values, as_dict=True)
return self.gl_entries
@@ -416,7 +448,6 @@ def get_pdc_details(party_type, report_date):
and pent.party_type = %s
group by pent.party, pref.reference_name""", (report_date, party_type), as_dict=1):
pdc_details.setdefault((pdc.invoice_no, pdc.party), pdc)
if scrub(party_type):
amount_field = ("jea.debit_in_account_currency"
if party_type == 'Supplier' else "jea.credit_in_account_currency")
@@ -443,18 +474,57 @@ def get_pdc_details(party_type, report_date):
return pdc_details
def get_dn_details(party_type):
def get_dn_details(party_type, voucher_nos):
dn_details = frappe._dict()
if party_type == "Customer":
for si in frappe.db.sql("""select parent, GROUP_CONCAT(delivery_note SEPARATOR ', ') as dn
from `tabSales Invoice Item`
where docstatus=1 and delivery_note is not null and delivery_note != '' group by parent
Union
select against_sales_invoice as parent, GROUP_CONCAT(parent SEPARATOR ', ') as dn
from `tabDelivery Note Item`
where docstatus=1 and against_sales_invoice is not null
and against_sales_invoice != '' group by against_sales_invoice""", as_dict=1):
for si in frappe.db.sql("""
select
parent, GROUP_CONCAT(delivery_note SEPARATOR ', ') as dn
from
`tabSales Invoice Item`
where
docstatus=1 and delivery_note is not null and delivery_note != ''
and parent in (%s) group by parent
""" %(','.join(['%s'] * len(voucher_nos))), tuple(voucher_nos) , as_dict=1):
dn_details.setdefault(si.parent, si.dn)
for si in frappe.db.sql("""
select
against_sales_invoice as parent, GROUP_CONCAT(parent SEPARATOR ', ') as dn
from
`tabDelivery Note Item`
where
docstatus=1 and against_sales_invoice is not null and against_sales_invoice != ''
and against_sales_invoice in (%s)
group by against_sales_invoice
""" %(','.join(['%s'] * len(voucher_nos))), tuple(voucher_nos) , as_dict=1):
if si.parent in dn_details:
dn_details[si.parent] += ', %s' %(si.dn)
else:
dn_details.setdefault(si.parent, si.dn)
return dn_details
def get_voucher_details(party_type, voucher_nos, dn_details):
voucher_details = frappe._dict()
if party_type == "Customer":
for si in frappe.db.sql("""select name, due_date, po_no
from `tabSales Invoice` where docstatus=1 and name in (%s)
""" %(','.join(['%s'] *len(voucher_nos))), (tuple(voucher_nos)), as_dict=1):
si['delivery_note'] = dn_details.get(si.name)
voucher_details.setdefault(si.name, si)
if party_type == "Supplier":
for pi in frappe.db.sql("""select name, due_date, bill_no, bill_date
from `tabPurchase Invoice` where docstatus = 1 and name in (%s)
""" %(','.join(['%s'] *len(voucher_nos))), (tuple(voucher_nos)), as_dict=1):
voucher_details.setdefault(pi.name, pi)
for pi in frappe.db.sql("""select name, due_date, bill_no, bill_date from
`tabJournal Entry` where docstatus = 1 and bill_no is not NULL and name in (%s)
""" %(','.join(['%s'] *len(voucher_nos))), (tuple(voucher_nos)), as_dict=1):
voucher_details.setdefault(pi.name, pi)
return voucher_details

View File

@@ -3,47 +3,75 @@
from __future__ import unicode_literals
import frappe
from frappe.utils import flt
from frappe import _
def execute(filters=None):
columns, data = get_columns(), get_data(filters)
return columns, data
def get_data(filters):
data = frappe.db.sql("""
select
a.name as asset, a.asset_category, a.status,
a.depreciation_method, a.purchase_date, a.gross_purchase_amount,
ds.schedule_date as depreciation_date, ds.depreciation_amount,
ds.accumulated_depreciation_amount,
(a.gross_purchase_amount - ds.accumulated_depreciation_amount) as amount_after_depreciation,
ds.journal_entry as depreciation_entry
from
`tabAsset` a, `tabDepreciation Schedule` ds
where
a.name = ds.parent
and a.docstatus=1
and ifnull(ds.journal_entry, '') != ''
and ds.schedule_date between %(from_date)s and %(to_date)s
and a.company = %(company)s
{conditions}
order by
a.name asc, ds.schedule_date asc
""".format(conditions=get_filter_conditions(filters)), filters, as_dict=1)
return data
def get_filter_conditions(filters):
conditions = ""
data = []
depreciation_accounts = frappe.db.sql_list(""" select name from tabAccount
where ifnull(account_type, '') = 'Depreciation' """)
filters_data = [["company", "=", filters.get('company')],
["posting_date", ">=", filters.get('from_date')],
["posting_date", "<=", filters.get('to_date')],
["against_voucher_type", "=", "Asset"],
["account", "in", depreciation_accounts]]
if filters.get("asset"):
conditions += " and a.name = %(asset)s"
filters_data.append(["against_voucher", "=", filters.get("asset")])
if filters.get("asset_category"):
conditions += " and a.asset_category = %(asset_category)s"
return conditions
assets = frappe.db.sql_list("""select name from tabAsset
where asset_category = %s and docstatus=1""", filters.get("asset_category"))
filters_data.append(["against_voucher", "in", assets])
gl_entries = frappe.get_all('GL Entry',
filters= filters_data,
fields = ["against_voucher", "debit_in_account_currency as debit", "voucher_no", "posting_date"],
order_by= "against_voucher, posting_date")
if not gl_entries:
return data
assets = [d.against_voucher for d in gl_entries]
assets_details = get_assets_details(assets)
for d in gl_entries:
asset_data = assets_details.get(d.against_voucher)
if not asset_data.get("accumulated_depreciation_amount"):
asset_data.accumulated_depreciation_amount = d.debit
else:
asset_data.accumulated_depreciation_amount += d.debit
row = frappe._dict(asset_data)
row.update({
"depreciation_amount": d.debit,
"depreciation_date": d.posting_date,
"amount_after_depreciation": (flt(row.gross_purchase_amount) -
flt(row.accumulated_depreciation_amount)),
"depreciation_entry": d.voucher_no
})
data.append(row)
return data
def get_assets_details(assets):
assets_details = {}
fields = ["name as asset", "gross_purchase_amount",
"asset_category", "status", "depreciation_method", "purchase_date"]
for d in frappe.get_all("Asset", fields = fields, filters = {'name': ('in', assets)}):
assets_details.setdefault(d.asset, d)
return assets_details
def get_columns():
return [
{

View File

@@ -39,6 +39,12 @@ frappe.query_reports["Budget Variance Report"] = {
options: ["Cost Center", "Project"],
default: "Cost Center",
reqd: 1
}
},
{
fieldname: "cost_center",
label: __("Cost Center"),
fieldtype: "Link",
options: "Cost Center"
},
]
}

View File

@@ -10,9 +10,13 @@ from erpnext.controllers.trends import get_period_date_ranges, get_period_month_
def execute(filters=None):
if not filters: filters = {}
validate_filters(filters)
columns = get_columns(filters)
cost_centers = get_cost_centers(filters)
if filters.get("cost_center"):
cost_centers = [filters.get("cost_center")]
else:
cost_centers = get_cost_centers(filters)
period_month_ranges = get_period_month_ranges(filters["period"], filters["fiscal_year"])
cam_map = get_cost_center_account_month_map(filters)
@@ -39,6 +43,10 @@ def execute(filters=None):
return columns, data
def validate_filters(filters):
if filters.get("budget_against")=="Project" and filters.get("cost_center"):
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:120"%(filters.get("budget_against")), _("Account") + ":Link/Account:120"]
@@ -66,12 +74,16 @@ def get_cost_centers(filters):
#Get cost center & target details
def get_cost_center_target_details(filters):
cond = ""
if filters.get("cost_center"):
cond += " and b.cost_center='%s'" % frappe.db.escape(filters.get("cost_center"))
return frappe.db.sql("""
select b.{budget_against} as budget_against, b.monthly_distribution, ba.account, ba.budget_amount
from `tabBudget` b, `tabBudget Account` ba
where b.name=ba.parent and b.docstatus = 1 and b.fiscal_year=%s
and b.budget_against = %s and b.company=%s
""".format(budget_against=filters.get("budget_against").replace(" ", "_").lower()),
and b.budget_against = %s and b.company=%s {cond}
""".format(budget_against=filters.get("budget_against").replace(" ", "_").lower(), cond=cond),
(filters.fiscal_year, filters.budget_against, filters.company), as_dict=True)
#Get target distribution details of accounts of cost center

View File

@@ -185,14 +185,15 @@ def prepare_data(accounts, balance_must_be, period_list, company_currency):
has_value = False
total = 0
row = frappe._dict({
"account_name": _(d.account_name),
"account": _(d.name),
"parent_account": _(d.parent_account),
"indent": flt(d.indent),
"year_start_date": year_start_date,
"year_end_date": year_end_date,
"currency": company_currency,
"opening_balance": d.get("opening_balance", 0.0) * (1 if balance_must_be=="Debit" else -1)
"opening_balance": d.get("opening_balance", 0.0) * (1 if balance_must_be=="Debit" else -1),
"account_name": ('{} - {}'.format(_(d.account_number), _(d.account_name))
if d.account_number else _(d.account_name))
})
for period in period_list:
if d.get(period.key) and balance_must_be=="Credit":
@@ -253,7 +254,7 @@ def add_total_row(out, root_type, balance_must_be, period_list, company_currency
out.append({})
def get_accounts(company, root_type):
return frappe.db.sql("""select name, parent_account, lft, rgt, root_type, report_type, account_name from `tabAccount`
return frappe.db.sql("""select name, account_number, parent_account, lft, rgt, root_type, report_type, account_name from `tabAccount`
where company=%s and root_type=%s order by lft""", (company, root_type), as_dict=True)
def filter_accounts(accounts, depth=10):
@@ -305,19 +306,20 @@ def set_gl_entries_by_account(company, from_date, to_date, root_lft, root_rgt, f
additional_conditions = get_additional_conditions(from_date, ignore_closing_entries, filters)
accounts = frappe.db.sql_list("""select name from `tabAccount`
where lft >= %s and rgt <= %s""", (root_lft, root_rgt))
additional_conditions += " and account in ('{}')"\
.format("', '".join([frappe.db.escape(d) for d in accounts]))
gl_entries = frappe.db.sql("""select posting_date, account, debit, credit, is_opening, fiscal_year from `tabGL Entry`
where company=%(company)s
{additional_conditions}
and posting_date <= %(to_date)s
and account in (select name from `tabAccount`
where lft >= %(lft)s and rgt <= %(rgt)s)
order by account, posting_date""".format(additional_conditions=additional_conditions),
{
"company": company,
"from_date": from_date,
"to_date": to_date,
"lft": root_lft,
"rgt": root_rgt
},
as_dict=True)

View File

@@ -71,8 +71,8 @@ def set_account_currency(filters):
if gle_currency:
account_currency = gle_currency
else:
account_currency = None if filters.party_type in ["Employee", "Student", "Shareholder"] else \
frappe.db.get_value(filters.party_type, filters.party, "default_currency")
account_currency = (None if filters.party_type in ["Employee", "Student", "Shareholder", "Member"] else
frappe.db.get_value(filters.party_type, filters.party, "default_currency"))
filters["account_currency"] = account_currency or filters.company_currency

View File

@@ -171,7 +171,7 @@ class GrossProfitGenerator(object):
row.qty += returned_item_row.qty
row.base_amount += returned_item_row.base_amount
row.buying_amount = row.qty * row.buying_rate
if row.qty:
if row.qty or row.base_amount:
row = self.set_average_rate(row)
self.grouped_data.append(row)

View File

@@ -49,7 +49,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
row += [
d.credit_to, d.mode_of_payment, d.project, d.company, d.purchase_order,
purchase_receipt, expense_account, d.stock_qty, d.stock_uom, d.base_net_rate, d.base_net_amount
purchase_receipt, expense_account, d.stock_qty, d.stock_uom, d.base_net_amount / d.stock_qty, d.base_net_amount
]
total_tax = 0
@@ -120,8 +120,7 @@ def get_items(filters, additional_query_columns):
`tabPurchase Invoice Item`.`project`, `tabPurchase Invoice Item`.`purchase_order`,
`tabPurchase Invoice Item`.`purchase_receipt`, `tabPurchase Invoice Item`.`po_detail`,
`tabPurchase Invoice Item`.`expense_account`, `tabPurchase Invoice Item`.`stock_qty`,
`tabPurchase Invoice Item`.`stock_uom`, `tabPurchase Invoice Item`.`base_net_rate`,
`tabPurchase Invoice Item`.`base_net_amount`,
`tabPurchase Invoice Item`.`stock_uom`, `tabPurchase Invoice Item`.`base_net_amount`,
`tabPurchase Invoice`.supplier_name, `tabPurchase Invoice`.mode_of_payment {0}
from `tabPurchase Invoice`, `tabPurchase Invoice Item`
where `tabPurchase Invoice`.name = `tabPurchase Invoice Item`.`parent` and

View File

@@ -53,7 +53,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
delivery_note, d.income_account, d.cost_center, d.stock_qty, d.stock_uom
]
row += [d.base_net_rate/d.stock_qty, d.base_net_amount] \
row += [(d.base_net_rate * d.qty)/d.stock_qty, d.base_net_amount] \
if d.stock_uom != d.uom else [d.base_net_rate, d.base_net_amount]
total_tax = 0
@@ -133,7 +133,7 @@ def get_items(filters, additional_query_columns):
`tabSales Invoice Item`.stock_uom, `tabSales Invoice Item`.base_net_rate,
`tabSales Invoice Item`.base_net_amount, `tabSales Invoice`.customer_name,
`tabSales Invoice`.customer_group, `tabSales Invoice Item`.so_detail,
`tabSales Invoice`.update_stock, `tabSales Invoice Item`.uom {0}
`tabSales Invoice`.update_stock, `tabSales Invoice Item`.uom, `tabSales Invoice Item`.qty {0}
from `tabSales Invoice`, `tabSales Invoice Item`
where `tabSales Invoice`.name = `tabSales Invoice Item`.parent
and `tabSales Invoice`.docstatus = 1 %s %s
@@ -157,6 +157,9 @@ def get_delivery_notes_against_sales_order(item_list):
return so_dn_map
def get_deducted_taxes():
return frappe.db.sql_list("select name from `tabPurchase Taxes and Charges` where add_deduct_tax = 'Deduct'")
def get_tax_accounts(item_list, columns, company_currency,
doctype="Sales Invoice", tax_doctype="Sales Taxes and Charges"):
import json
@@ -176,9 +179,10 @@ def get_tax_accounts(item_list, columns, company_currency,
if doctype == "Purchase Invoice":
conditions = " and category in ('Total', 'Valuation and Total') and base_tax_amount_after_discount_amount != 0"
deducted_tax = get_deducted_taxes()
tax_details = frappe.db.sql("""
select
parent, description, item_wise_tax_detail,
name, parent, description, item_wise_tax_detail,
charge_type, base_tax_amount_after_discount_amount
from `tab%s`
where
@@ -190,7 +194,7 @@ def get_tax_accounts(item_list, columns, company_currency,
""" % (tax_doctype, '%s', ', '.join(['%s']*len(invoice_item_row)), conditions),
tuple([doctype] + invoice_item_row.keys()))
for parent, description, item_wise_tax_detail, charge_type, tax_amount in tax_details:
for name, parent, description, item_wise_tax_detail, charge_type, tax_amount in tax_details:
description = handle_html(description)
if description not in tax_columns and tax_amount:
# as description is text editor earlier and markup can break the column convention in reports
@@ -219,9 +223,13 @@ def get_tax_accounts(item_list, columns, company_currency,
item_tax_amount = flt((tax_amount * d.base_net_amount) / item_net_amount) \
if item_net_amount else 0
if item_tax_amount:
tax_value = flt(item_tax_amount, tax_amount_precision)
tax_value = (tax_value * -1
if (doctype == 'Purchase Invoice' and name in deducted_tax) else tax_value)
itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
"tax_rate": tax_rate,
"tax_amount": flt(item_tax_amount, tax_amount_precision)
"tax_amount": tax_value
})
except ValueError:

View File

@@ -51,7 +51,7 @@ def validate_filters(filters):
filters.to_date = filters.year_end_date
def get_data(filters):
accounts = frappe.db.sql("""select name, parent_account, account_name, root_type, report_type, lft, rgt
accounts = frappe.db.sql("""select name, account_number, parent_account, account_name, root_type, report_type, lft, rgt
from `tabAccount` where company=%s order by lft""", filters.company, as_dict=True)
company_currency = erpnext.get_company_currency(filters.company)
@@ -162,8 +162,6 @@ def calculate_values(accounts, gl_entries_by_account, opening_balances, filters,
total_row["credit"] += d["credit"]
total_row["opening_debit"] += d["opening_debit"]
total_row["opening_credit"] += d["opening_credit"]
total_row["closing_debit"] += (d["opening_debit"] + d["debit"])
total_row["closing_credit"] += (d["opening_credit"] + d["credit"])
return total_row
@@ -176,16 +174,19 @@ def accumulate_values_into_parents(accounts, accounts_by_name):
def prepare_data(accounts, filters, total_row, parent_children_map, company_currency):
data = []
total_row["closing_debit"] = total_row["closing_credit"] = 0
for d in accounts:
has_value = False
row = {
"account_name": d.account_name,
"account": d.name,
"parent_account": d.parent_account,
"indent": d.indent,
"from_date": filters.from_date,
"to_date": filters.to_date,
"currency": company_currency
"currency": company_currency,
"account_name": ('{} - {}'.format(d.account_number, d.account_name)
if d.account_number else d.account_name)
}
prepare_opening_and_closing(d)
@@ -200,6 +201,10 @@ def prepare_data(accounts, filters, total_row, parent_children_map, company_curr
row["has_value"] = has_value
data.append(row)
if not d.parent_account:
total_row["closing_debit"] += (d["debit"] - d["credit"]) if (d["debit"] - d["credit"]) > 0 else 0
total_row["closing_credit"] += abs(d["debit"] - d["credit"]) if (d["debit"] - d["credit"]) < 0 else 0
data.extend([{},total_row])
return data

View File

@@ -23,6 +23,14 @@ frappe.ui.form.on('Asset', {
}
};
});
frm.set_query("cost_center", function() {
return {
"filters": {
"company": frm.doc.company,
}
};
});
},
refresh: function(frm) {
@@ -59,11 +67,33 @@ frappe.ui.form.on('Asset', {
frm.trigger("create_asset_maintenance");
}, __("Make"));
}
if (!frm.doc.calculate_depreciation) {
frm.add_custom_button(__("Depreciation Entry"), function() {
frm.trigger("make_journal_entry");
}, __("Make"));
}
frm.page.set_inner_btn_group_as_primary(__("Make"));
frm.trigger("setup_chart");
}
},
make_journal_entry: function(frm) {
frappe.call({
method: "erpnext.assets.doctype.asset.asset.make_journal_entry",
args: {
asset_name: frm.doc.name
},
callback: function(r) {
if (r.message) {
var doclist = frappe.model.sync(r.message);
frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
}
}
})
},
setup_chart: function(frm) {
var x_intervals = [frm.doc.purchase_date];
var asset_values = [frm.doc.gross_purchase_amount];

View File

@@ -415,6 +415,37 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "cost_center",
"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": "Cost Center",
"length": 0,
"no_copy": 0,
"options": "Cost Center",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -1221,7 +1252,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-12-19 12:58:44.137460",
"modified": "2018-07-17 06:30:25.506194",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset",

View File

@@ -283,3 +283,34 @@ def get_item_details(item_code):
})
return ret
@frappe.whitelist()
def make_journal_entry(asset_name):
asset = frappe.get_doc("Asset", asset_name)
fixed_asset_account, accumulated_depreciation_account, depreciation_expense_account = \
get_depreciation_accounts(asset)
depreciation_cost_center, depreciation_series = frappe.db.get_value("Company", asset.company,
["depreciation_cost_center", "series_for_depreciation_entry"])
depreciation_cost_center = asset.cost_center or depreciation_cost_center
je = frappe.new_doc("Journal Entry")
je.voucher_type = "Depreciation Entry"
je.naming_series = depreciation_series
je.company = asset.company
je.remark = "Depreciation Entry against asset {0}".format(asset_name)
je.append("accounts", {
"account": depreciation_expense_account,
"reference_type": "Asset",
"reference_name": asset.name,
"cost_center": depreciation_cost_center
})
je.append("accounts", {
"account": accumulated_depreciation_account,
"reference_type": "Asset",
"reference_name": asset.name
})
return je

View File

@@ -5,13 +5,13 @@
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import flt, today, getdate
from frappe.utils import flt, today, getdate, cint
def post_depreciation_entries(date=None):
# Return if automatic booking of asset depreciation is disabled
if not frappe.db.get_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically"):
if not cint(frappe.db.get_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically")):
return
if not date:
date = today()
for asset in get_depreciable_assets(date):
@@ -38,7 +38,7 @@ def make_depreciation_entry(asset_name, date=None):
depreciation_cost_center, depreciation_series = frappe.db.get_value("Company", asset.company,
["depreciation_cost_center", "series_for_depreciation_entry"])
depreciation_cost_center = asset.cost_center or depreciation_cost_center
for d in asset.get("schedules"):
if not d.journal_entry and getdate(d.schedule_date) <= getdate(date):
@@ -154,6 +154,7 @@ def restore_asset(asset_name):
def get_gl_entries_on_asset_disposal(asset, selling_amount=0):
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)

View File

@@ -22,7 +22,7 @@ frappe.ui.form.on('Asset Category', {
var d = locals[cdt][cdn];
return {
"filters": {
"root_type": "Asset",
"account_type": "Accumulated Depreciation",
"is_group": 0,
"company": d.company_name
}
@@ -41,4 +41,4 @@ frappe.ui.form.on('Asset Category', {
});
}
});
});

View File

@@ -3,7 +3,7 @@
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "field:maintenance_task",
"autoname": "",
"beta": 0,
"creation": "2017-10-20 07:10:55.903571",
"custom": 0,
@@ -42,7 +42,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 1
"unique": 0
},
{
"allow_bulk_edit": 0,
@@ -625,7 +625,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2017-11-28 12:22:34.151430",
"modified": "2018-06-18 16:12:04.330021",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset Maintenance Task",

View File

@@ -7,4 +7,5 @@ import frappe
from frappe.model.document import Document
class AssetMaintenanceTask(Document):
pass
def autoname(self):
self.name = self.maintenance_task

View File

@@ -1,231 +1,276 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2013-06-25 11:04:03",
"custom": 0,
"description": "Settings for Buying Module",
"docstatus": 0,
"doctype": "DocType",
"document_type": "Other",
"editable_grid": 0,
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Supplier Name",
"fieldname": "supp_master_name",
"fieldtype": "Select",
"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": "Supplier Naming By",
"length": 0,
"no_copy": 0,
"options": "Supplier Name\nNaming Series",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "supplier_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": "Default Supplier Type",
"length": 0,
"no_copy": 0,
"options": "Supplier Type",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "buying_price_list",
"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": "Default Buying Price List",
"length": 0,
"no_copy": 0,
"options": "Price List",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_3",
"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,
"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_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "po_required",
"fieldtype": "Select",
"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": "Purchase Order Required",
"length": 0,
"no_copy": 0,
"options": "No\nYes",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "pr_required",
"fieldtype": "Select",
"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": "Purchase Receipt Required",
"length": 0,
"no_copy": 0,
"options": "No\nYes",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "maintain_same_rate",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Maintain same rate throughout purchase cycle",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "allow_multiple_items",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Allow Item to be added multiple times in a transaction",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"description": "If enabled, last purchase details of items will not be fetched from previous purchase order or purchase receipt",
"fieldname": "disable_fetch_last_purchase_rate",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Disable Fetching Last Purchase Details in Purchase Order",
"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
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-cog",
"idx": 1,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 1,
"istable": 0,
"modified": "2017-12-27 15:20:06.052342",
"max_attachments": 0,
"modified": "2018-07-18 07:52:38.062488",
"modified_by": "Administrator",
"module": "Buying",
"name": "Buying Settings",
@@ -252,6 +297,10 @@
"write": 1
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0
"read_only_onload": 0,
"show_name_in_global_search": 0,
"track_changes": 0,
"track_seen": 0
}

View File

@@ -32,12 +32,7 @@ frappe.ui.form.on("Purchase Order", {
erpnext.queries.setup_queries(frm, "Warehouse", function() {
return erpnext.queries.warehouse(frm.doc);
});
if (frm.doc.__onload) {
frm.toggle_display('get_last_purchase_rate',
frm.doc.__onload.disable_fetch_last_purchase_rate);
}
},
}
});
frappe.ui.form.on("Purchase Order Item", {
@@ -318,6 +313,73 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
})
}, __("Add items from"));
this.frm.add_custom_button(__('Update rate as per last purchase'),
function() {
frappe.call({
"method": "get_last_purchase_rate",
"doc": me.frm.doc,
callback: function(r, rt) {
me.frm.dirty();
me.frm.cscript.calculate_taxes_and_totals();
}
})
}, __("Tools"));
this.frm.add_custom_button(__('Link to Material Request'),
function() {
var my_items = [];
for (var i in me.frm.doc.items) {
if(!me.frm.doc.items[i].material_request){
my_items.push(me.frm.doc.items[i].item_code);
}
}
frappe.call({
method: "erpnext.buying.utils.get_linked_material_requests",
args:{
items: my_items
},
callback: function(r) {
if(r.exc) return;
var i = 0;
var item_length = me.frm.doc.items.length;
while (i < item_length) {
var qty = me.frm.doc.items[i].qty;
(r.message[0] || []).forEach(function(d) {
if (d.qty > 0 && qty > 0 && me.frm.doc.items[i].item_code == d.item_code && !me.frm.doc.items[i].material_request_item)
{
me.frm.doc.items[i].material_request = d.mr_name;
me.frm.doc.items[i].material_request_item = d.mr_item;
var my_qty = Math.min(qty, d.qty);
qty = qty - my_qty;
d.qty = d.qty - my_qty;
me.frm.doc.items[i].stock_qty = my_qty * me.frm.doc.items[i].conversion_factor;
me.frm.doc.items[i].qty = my_qty;
frappe.msgprint("Assigning " + d.mr_name + " to " + d.item_code + " (row " + me.frm.doc.items[i].idx + ")");
if (qty > 0) {
frappe.msgprint("Splitting " + qty + " units of " + d.item_code);
var new_row = frappe.model.add_child(me.frm.doc, me.frm.doc.items[i].doctype, "items");
item_length++;
for (var key in me.frm.doc.items[i]) {
new_row[key] = me.frm.doc.items[i][key];
}
new_row.idx = item_length;
new_row["stock_qty"] = new_row.conversion_factor * qty;
new_row["qty"] = qty;
new_row["material_request"] = "";
new_row["material_request_item"] = "";
}
}
});
i++;
}
refresh_field("items");
}
});
}, __("Tools"));
},
tc_name: function() {
@@ -346,17 +408,6 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
cur_frm.cscript.update_status('Deliver', 'Delivered')
},
get_last_purchase_rate: function() {
frappe.call({
"method": "get_last_purchase_rate",
"doc": cur_frm.doc,
callback: function(r, rt) {
cur_frm.dirty();
cur_frm.cscript.calculate_taxes_and_totals();
}
})
},
items_on_form_rendered: function() {
set_schedule_date(this.frm);
},

View File

@@ -1207,7 +1207,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_bulk_edit": 1,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1238,68 +1238,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.docstatus===0 && (doc.items && doc.items.length)",
"fieldname": "get_last_purchase_rate",
"fieldtype": "Button",
"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": "Get last purchase 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": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.docstatus===0 && (doc.items && doc.items.length)",
"fieldname": "link_to_mrs",
"fieldtype": "Button",
"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": "Link to material requests",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -2440,6 +2378,37 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "rounded_total",
"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": "Rounded Total",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -2471,6 +2440,36 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "disable_rounded_total",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Disable Rounded Total",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -3355,7 +3354,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-02-17 11:00:05.037716",
"modified": "2018-08-01 15:18:33.155409",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order",

View File

@@ -33,12 +33,6 @@ class PurchaseOrder(BuyingController):
'percent_join_field': 'material_request'
}]
def onload(self):
super(PurchaseOrder, self).onload()
self.set_onload('disable_fetch_last_purchase_rate',
cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")))
def validate(self):
super(PurchaseOrder, self).validate()
@@ -122,7 +116,6 @@ class PurchaseOrder(BuyingController):
def get_last_purchase_rate(self):
"""get last purchase rates for all items"""
if cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")): return
conversion_rate = flt(self.get('conversion_rate')) or 1.0
for d in self.get("items"):
@@ -286,7 +279,6 @@ class PurchaseOrder(BuyingController):
def item_last_purchase_rate(name, conversion_rate, item_code, conversion_factor= 1.0):
"""get last purchase rate for an item"""
if cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")): return
conversion_rate = flt(conversion_rate) or 1.0

View File

@@ -1,156 +0,0 @@
QUnit.module('Buying');
QUnit.test("test: purchase order with last purchase rate", function(assert) {
assert.expect(9);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make('Purchase Order', [
{supplier: 'Test Supplier'},
{is_subcontracted: 'No'},
{currency: 'INR'},
{items: [
[
{"item_code": 'Test Product 4'},
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
{"qty": 1},
{"rate": 800},
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
],
[
{"item_code": 'Test Product 1'},
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
{"qty": 1},
{"rate": 400},
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
]
]}
]);
},
() => {
// Get item details
assert.ok(cur_frm.doc.items[0].item_name == 'Test Product 4', "Item 1 name correct");
assert.ok(cur_frm.doc.items[1].item_name == 'Test Product 1', "Item 2 name correct");
},
() => frappe.timeout(1),
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(3),
() => frappe.tests.click_button('Close'),
() => frappe.timeout(1),
() => {
return frappe.tests.make('Purchase Order', [
{supplier: 'Test Supplier'},
{is_subcontracted: 'No'},
{currency: 'INR'},
{items: [
[
{"item_code": 'Test Product 4'},
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
{"qty": 1},
{"rate": 600},
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
],
[
{"item_code": 'Test Product 1'},
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
{"qty": 1},
{"rate": 200},
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
]
]}
]);
},
() => frappe.timeout(2),
// Get the last purchase rate of items
() => {
assert.ok(cur_frm.doc.items[0].last_purchase_rate == 800, "Last purchase rate of item 1 correct");
assert.ok(cur_frm.doc.items[1].last_purchase_rate != 0);
},
() => {
assert.ok(cur_frm.doc.items[1].last_purchase_rate == 400, "Last purchase rate of item 2 correct");
assert.ok(cur_frm.doc.items[1].last_purchase_rate != 0);
},
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(3),
() => frappe.tests.click_button('Close'),
() => frappe.timeout(1),
() => {
assert.ok(cur_frm.doc.status == 'To Receive and Bill', "Submitted successfully");
},
// enable allow_last_purchase_rate
() => {
return frappe.tests.make('Buying Settings', [
// values to be set
{"disable_fetch_last_purchase_rate": 1}
]);
},
() => {
return frappe.tests.make('Purchase Order', [
{supplier: 'Test Supplier'},
{is_subcontracted: 'No'},
{currency: 'INR'},
{items: [
[
{"item_code": 'Test Product 4'},
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
{"qty": 1},
{"rate": 800},
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
],
[
{"item_code": 'Test Product 1'},
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
{"qty": 1},
{"rate": 400},
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
]
]}
]);
},
() => {
// Get item details
assert.ok(cur_frm.doc.items[0].last_purchase_rate == 0);
assert.ok(cur_frm.doc.items[1].last_purchase_rate == 0);
},
() => frappe.timeout(1),
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(3),
() => frappe.tests.click_button('Close'),
() => frappe.timeout(1),
// enable allow_last_purchase_rate
() => frappe.tests.make('Buying Settings', [
// values to be set
{"disable_fetch_last_purchase_rate": 0}
]),
() => done()
]);
});

View File

@@ -629,6 +629,38 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "discount_percentage",
"fieldname": "discount_amount",
"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": "Discount Amount",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -680,7 +712,7 @@
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
@@ -1897,7 +1929,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2017-12-14 09:36:40.837027",
"modified": "2018-08-06 05:16:58.258276",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order Item",

View File

@@ -781,7 +781,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_bulk_edit": 1,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1983,6 +1983,37 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "rounded_total",
"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": "Rounded Total",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -2014,6 +2045,36 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "disable_rounded_total",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Disable Rounded Total",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -2171,6 +2232,65 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "group_same_items",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Group same items",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_72",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 1,
@@ -2490,7 +2610,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2017-11-29 14:07:56.698355",
"modified": "2018-08-01 15:18:23.265621",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Quotation",

View File

@@ -60,7 +60,12 @@ class SupplierQuotation(BuyingController):
for rfq in rfq_list:
doc = frappe.get_doc('Request for Quotation', rfq)
doc_sup = frappe.get_all('Request for Quotation Supplier', filters=
{'parent': doc.name, 'supplier': self.supplier}, fields=['name', 'quote_status'])[0]
{'parent': doc.name, 'supplier': self.supplier}, fields=['name', 'quote_status'])
doc_sup = doc_sup[0] if doc_sup else None
if not doc_sup:
frappe.throw(_("Supplier {0} not found in {1}").format(self.supplier,
"<a href='desk#Form/Request for Quotation/{0}'> Request for Quotation {0} </a>".format(doc.name)))
quote_status = _('Received')
for item in doc.items:
@@ -152,4 +157,4 @@ def make_quotation(source_name, target_doc=None):
}
}, target_doc)
return doclist
return doclist

View File

@@ -470,6 +470,38 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "discount_percentage",
"fieldname": "discount_amount",
"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": "Discount Amount",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -1645,7 +1677,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2018-01-25 15:04:40.171617",
"modified": "2018-08-06 05:33:07.404385",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Quotation Item",

View File

@@ -291,14 +291,6 @@ def get_data():
"label": _("Healthcare"),
"hidden": 1
},
{
"module_name": "Hub",
"color": "#009248",
"icon": "/assets/erpnext/images/hub_logo.svg",
"type": "page",
"link": "hub",
"label": _("Hub")
},
{
"module_name": "Data Import",
"color": "#FFF168",

View File

@@ -1,3 +1,3 @@
from __future__ import unicode_literals
source_link = "https://github.com/frappe/erpnext"
source_link = "https://github.com/erpnext/foundation"

View File

@@ -36,13 +36,13 @@ def get_data():
"items": [
{
"type": "doctype",
"name": "Job Applicant",
"description": _("Applicant for a Job."),
"name": "Job Opening",
"description": _("Opening for a Job."),
},
{
"type": "doctype",
"name": "Job Opening",
"description": _("Opening for a Job."),
"name": "Job Applicant",
"description": _("Applicant for a Job."),
},
{
"type": "doctype",

View File

@@ -1,24 +0,0 @@
from __future__ import unicode_literals
from frappe import _
def get_data():
return [
{
"label": _("Setup"),
"items": [
{
"type": "doctype",
"name": "Hub Settings"
},
]
},
{
"label": _("Hub"),
"items": [
{
"type": "page",
"name": "hub"
},
]
},
]

View File

@@ -82,7 +82,8 @@ class AccountsController(TransactionBase):
self.validate_non_invoice_documents_schedule()
def before_print(self):
if self.doctype in ['Purchase Order', 'Sales Order']:
if self.doctype in ['Purchase Order', 'Sales Order', 'Sales Invoice', 'Purchase Invoice',
'Supplier Quotation', 'Purchase Receipt', 'Delivery Note', 'Quotation']:
if self.get("group_same_items"):
self.group_similar_items()
@@ -130,14 +131,18 @@ class AccountsController(TransactionBase):
self.meta.get_label(date_field), self)
def validate_due_date(self):
if self.get('is_pos'): return
from erpnext.accounts.party import validate_due_date
if self.doctype == "Sales Invoice":
if not self.due_date:
frappe.throw(_("Due Date is mandatory"))
validate_due_date(self.posting_date, self.due_date, "Customer", self.customer, self.company)
validate_due_date(self.posting_date, self.due_date,
"Customer", self.customer, self.company, self.payment_terms_template)
elif self.doctype == "Purchase Invoice":
validate_due_date(self.posting_date, self.due_date, "Supplier", self.supplier, self.company)
validate_due_date(self.posting_date, self.due_date,
"Supplier", self.supplier, self.company, self.payment_terms_template)
def set_price_list_currency(self, buying_or_selling):
if self.meta.get_field("posting_date"):
@@ -232,7 +237,7 @@ class AccountsController(TransactionBase):
tax_master_doctype = self.meta.get_field("taxes_and_charges").options
if self.is_new() and not self.get("taxes"):
if (self.is_new() or self.is_pos_profile_changed()) and not self.get("taxes"):
if self.company and not self.get("taxes_and_charges"):
# get the default tax master
self.taxes_and_charges = frappe.db.get_value(tax_master_doctype,
@@ -240,6 +245,11 @@ class AccountsController(TransactionBase):
self.append_taxes_from_master(tax_master_doctype)
def is_pos_profile_changed(self):
if (self.doctype == 'Sales Invoice' and self.is_pos and
self.pos_profile != frappe.db.get_value('Sales Invoice', self.name, 'pos_profile')):
return True
def append_taxes_from_master(self, tax_master_doctype=None):
if self.get("taxes_and_charges"):
if not tax_master_doctype:
@@ -658,6 +668,7 @@ class AccountsController(TransactionBase):
if item.item_code in group_item_qty:
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"))
del group_item_qty[item.item_code]
else:
duplicate_list.append(item)

View File

@@ -35,6 +35,7 @@ class BuyingController(StockController):
if getattr(self, "supplier", None) and not self.supplier_name:
self.supplier_name = frappe.db.get_value("Supplier", self.supplier, "supplier_name")
self.validate_items()
self.set_qty_as_per_stock_uom()
self.validate_stock_or_nonstock_items()
self.validate_warehouse()
@@ -98,9 +99,16 @@ class BuyingController(StockController):
def set_total_in_words(self):
from frappe.utils import money_in_words
if self.meta.get_field("base_in_words"):
self.base_in_words = money_in_words(self.base_grand_total, self.company_currency)
amount = (self.base_rounded_total
if not self.get("disable_rounded_total") else self.base_grand_total)
self.base_in_words = money_in_words(amount, self.company_currency)
if self.meta.get_field("in_words"):
self.in_words = money_in_words(self.grand_total, self.currency)
amount = (self.rounded_total
if not self.get("disable_rounded_total") else self.grand_total)
self.in_words = money_in_words(amount, self.currency)
# update valuation rate
def update_valuation_rate(self, parentfield):
@@ -456,3 +464,32 @@ class BuyingController(StockController):
else:
frappe.throw(_("Please enter Reqd by Date"))
def validate_items(self):
# validate items to see if they have is_purchase_item or is_subcontracted_item enabled
if self.doctype=="Material Request": return
if hasattr(self, "is_subcontracted") and self.is_subcontracted == 'Yes':
validate_item_type(self, "is_sub_contracted_item", "subcontracted")
else:
validate_item_type(self, "is_purchase_item", "purchase")
def validate_item_type(doc, fieldname, message):
# iterate through items and check if they are valid sales or purchase items
items = [d.item_code for d in doc.items if d.item_code]
# No validation check inase of creating transaction using 'Opening Invoice Creation Tool'
if not items:
return
item_list = ", ".join(["'%s'" % frappe.db.escape(d) for d in items])
invalid_items = [d[0] for d in frappe.db.sql("""
select item_code from tabItem where name in ({0}) and {1}=0
""".format(item_list, fieldname), as_list=True)]
if invalid_items:
frappe.throw(_("Following item {items} {verb} not marked as {message} item.\
You can enable them as {message} item from its Item master".format(
items = ", ".join([d for d in invalid_items]),
verb = "are" if len(invalid_items) > 1 else "is",
message = message)))

View File

@@ -176,6 +176,14 @@ def create_variant(item, args):
@frappe.whitelist()
def enqueue_multiple_variant_creation(item, args):
# There can be innumerable attribute combinations, enqueue
if isinstance(args, basestring):
variants = json.loads(args)
total_variants = 1
for key in variants:
total_variants *= len(variants[key])
if total_variants >= 600:
frappe.msgprint("Please do not create more than 500 items at a time", raise_exception=1)
return
frappe.enqueue("erpnext.controllers.item_variant.create_multiple_variants",
item=item, args=args, now=frappe.flags.in_test);

View File

@@ -157,9 +157,10 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals
# scan description only if items are less than 50000
description_cond = 'or tabItem.description LIKE %(txt)s'
return frappe.db.sql("""select tabItem.name, tabItem.item_group,
return frappe.db.sql("""select tabItem.name,
if(length(tabItem.item_name) > 40,
concat(substr(tabItem.item_name, 1, 40), "..."), item_name) as item_name,
tabItem.item_group,
if(length(tabItem.description) > 40, \
concat(substr(tabItem.description, 1, 40), "..."), description) as decription
from tabItem
@@ -217,7 +218,8 @@ def bom(doctype, txt, searchfield, start, page_len, filters):
def get_project_name(doctype, txt, searchfield, start, page_len, filters):
cond = ''
if filters.get('customer'):
cond = '(`tabProject`.customer = "' + filters['customer'] + '" or ifnull(`tabProject`.customer,"")="") and'
cond = """(`tabProject`.customer = '%s' or
ifnull(`tabProject`.customer,"")="") and""" %(frappe.db.escape(filters.get("customer")))
return frappe.db.sql("""select `tabProject`.name from `tabProject`
where `tabProject`.status not in ("Completed", "Cancelled")

View File

@@ -83,15 +83,15 @@ def validate_returned_items(doc):
else:
ref = valid_items.get(d.item_code, frappe._dict())
validate_quantity(doc, d, ref, valid_items, already_returned_items)
if ref.rate and doc.doctype in ("Delivery Note", "Sales Invoice") and flt(d.rate) > ref.rate:
frappe.throw(_("Row # {0}: Rate cannot be greater than the rate used in {1} {2}")
.format(d.idx, doc.doctype, doc.return_against))
elif ref.batch_no and d.batch_no not in ref.batch_no:
frappe.throw(_("Row # {0}: Batch No must be same as {1} {2}")
.format(d.idx, doc.doctype, doc.return_against))
elif ref.serial_no:
if not d.serial_no:
frappe.throw(_("Row # {0}: Serial No is mandatory").format(d.idx))
@@ -120,25 +120,30 @@ def validate_quantity(doc, args, ref, valid_items, already_returned_items):
for column in fields:
returned_qty = flt(already_returned_data.get(column, 0)) if len(already_returned_data) > 0 else 0
reference_qty = (ref.get(column) if column == 'stock_qty'
else ref.get(column) * ref.get("conversion_factor", 1.0))
if column == 'stock_qty':
reference_qty = ref.get(column)
current_stock_qty = args.get(column)
else:
reference_qty = ref.get(column) * ref.get("conversion_factor", 1.0)
current_stock_qty = args.get(column) * args.get("conversion_factor", 1.0)
max_returnable_qty = flt(reference_qty) - returned_qty
label = column.replace('_', ' ').title()
if reference_qty:
if reference_qty:
if flt(args.get(column)) > 0:
frappe.throw(_("{0} must be negative in return document").format(label))
elif returned_qty >= reference_qty and args.get(column):
frappe.throw(_("Item {0} has already been returned")
.format(args.item_code), StockOverReturnError)
elif (abs(args.get(column)) * args.get("conversion_factor", 1.0)) > max_returnable_qty:
elif abs(current_stock_qty) > max_returnable_qty:
frappe.throw(_("Row # {0}: Cannot return more than {1} for Item {2}")
.format(args.idx, reference_qty, args.item_code), StockOverReturnError)
.format(args.idx, max_returnable_qty, args.item_code), StockOverReturnError)
def get_ref_item_dict(valid_items, ref_item_row):
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
valid_items.setdefault(ref_item_row.item_code, frappe._dict({
"qty": 0,
"rate": 0,
@@ -146,6 +151,7 @@ def get_ref_item_dict(valid_items, ref_item_row):
"rejected_qty": 0,
"received_qty": 0,
"serial_no": [],
"conversion_factor": ref_item_row.get("conversion_factor", 1),
"batch_no": []
}))
item_dict = valid_items[ref_item_row.item_code]
@@ -160,10 +166,10 @@ def get_ref_item_dict(valid_items, ref_item_row):
if ref_item_row.get("serial_no"):
item_dict["serial_no"] += get_serial_nos(ref_item_row.serial_no)
if ref_item_row.get("batch_no"):
item_dict["batch_no"].append(ref_item_row.batch_no)
return valid_items
def get_already_returned_items(doc):

View File

@@ -35,6 +35,7 @@ class SellingController(StockController):
def validate(self):
super(SellingController, self).validate()
self.validate_items()
self.validate_max_discount()
self.validate_selling_price()
self.set_qty_as_per_stock_uom()
@@ -51,9 +52,15 @@ class SellingController(StockController):
def set_missing_lead_customer_details(self):
if getattr(self, "customer", None):
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,
ignore_permissions=self.flags.ignore_permissions,
doctype=self.doctype, company=self.company)
doctype=self.doctype, company=self.company,
fetch_payment_terms_template=fetch_payment_terms_template)
if not self.meta.get_field("sales_team"):
party_details.pop("sales_team")
@@ -337,6 +344,11 @@ class SellingController(StockController):
po_nos = frappe.get_all('Sales Order', 'po_no', filters = {'name': ('in', sales_orders)})
self.po_no = ', '.join(list(set([d.po_no for d in po_nos if d.po_no])))
def validate_items(self):
# validate items to see if they have is_sales_item enabled
from erpnext.controllers.buying_controller import validate_item_type
validate_item_type(self, "is_sales_item", "sales")
def check_active_sales_items(obj):
for d in obj.get("items"):
if d.item_code:

View File

@@ -29,6 +29,7 @@ class calculate_taxes_and_totals(object):
self.set_item_wise_tax_breakup()
def _calculate(self):
self.validate_conversion_rate()
self.calculate_item_values()
self.initialize_taxes()
self.determine_exclusive_rate()
@@ -37,6 +38,7 @@ class calculate_taxes_and_totals(object):
self.manipulate_grand_total_for_inclusive_tax()
self.calculate_totals()
self._cleanup()
self.calculate_total_net_weight()
def validate_conversion_rate(self):
# validate conversion rate
@@ -327,6 +329,13 @@ class calculate_taxes_and_totals(object):
self.set_rounded_total()
def calculate_total_net_weight(self):
if self.doc.meta.get_field('total_net_weight'):
self.doc.total_net_weight = 0.0
for d in self.doc.items:
if d.total_weight:
self.doc.total_net_weight += d.total_weight
def set_rounded_total(self):
if self.doc.meta.get_field("rounded_total"):
if self.doc.is_rounded_total_disabled():
@@ -557,7 +566,8 @@ def get_itemised_tax_breakup_html(doc):
itemised_tax=itemised_tax,
itemised_taxable_amount=itemised_taxable_amount,
tax_accounts=tax_accounts,
company_currency=erpnext.get_company_currency(doc.company)
conversion_rate=doc.conversion_rate,
currency=doc.currency
)
)
@@ -590,16 +600,19 @@ def get_itemised_tax(taxes):
for item_code, tax_data in item_tax_map.items():
itemised_tax.setdefault(item_code, frappe._dict())
tax_rate = 0.0
tax_amount = 0.0
if isinstance(tax_data, list):
itemised_tax[item_code][tax.description] = frappe._dict(dict(
tax_rate=flt(tax_data[0]),
tax_amount=flt(tax_data[1])
))
tax_rate = flt(tax_data[0])
tax_amount = flt(tax_data[1])
else:
itemised_tax[item_code][tax.description] = frappe._dict(dict(
tax_rate=flt(tax_data),
tax_amount=0.0
))
tax_rate = flt(tax_data)
itemised_tax[item_code][tax.description] = frappe._dict(dict(
tax_rate = tax_rate,
tax_amount = tax_amount
))
return itemised_tax

View File

@@ -20,6 +20,10 @@ frappe.ui.form.on("Opportunity", {
frm.trigger('set_contact_link');
},
with_items: function(frm) {
frm.trigger('toggle_mandatory');
},
customer_address: function(frm, cdt, cdn) {
erpnext.utils.get_address_display(frm, 'customer_address', 'address_display', false);
},
@@ -35,6 +39,7 @@ frappe.ui.form.on("Opportunity", {
var doc = frm.doc;
frm.events.enquiry_from(frm);
frm.trigger('set_contact_link');
frm.trigger('toggle_mandatory');
erpnext.toggle_naming_series();
if(!doc.__islocal && doc.status!=="Lost") {
@@ -84,6 +89,10 @@ frappe.ui.form.on("Opportunity", {
method: "erpnext.crm.doctype.opportunity.opportunity.make_supplier_quotation",
frm: cur_frm
})
},
toggle_mandatory: function(frm) {
frm.toggle_reqd("items", frm.doc.with_items ? 1:0);
}
})

View File

@@ -51,12 +51,12 @@ def enroll_random_student(current_date):
def assign_student_group(student, student_name, program, courses, batch):
course_list = [d["course"] for d in courses]
for d in frappe.get_list("Student Group", fields=("name"), filters={"program": program, "course":("in", course_list)}):
for d in frappe.get_list("Student Group", fields=("name"), filters={"program": program, "course":("in", course_list), "disabled": 0}):
student_group = frappe.get_doc("Student Group", d.name)
student_group.append("students", {"student": student, "student_name": student_name,
"group_roll_number":len(student_group.students)+1, "active":1})
student_group.save()
student_batch = frappe.get_list("Student Group", fields=("name"), filters={"program": program, "group_based_on":"Batch", "batch":batch})[0]
student_batch = frappe.get_list("Student Group", fields=("name"), filters={"program": program, "group_based_on":"Batch", "batch":batch, "disabled": 0})[0]
student_batch_doc = frappe.get_doc("Student Group", student_batch.name)
student_batch_doc.append("students", {"student": student, "student_name": student_name,
"group_roll_number":len(student_batch_doc.students)+1, "active":1})
@@ -65,7 +65,7 @@ def assign_student_group(student, student_name, program, courses, batch):
def mark_student_attendance(current_date):
status = ["Present", "Absent"]
for d in frappe.db.get_list("Student Group", filters={"group_based_on": "Batch"}):
for d in frappe.db.get_list("Student Group", filters={"group_based_on": "Batch", "disabled": 0}):
students = get_student_group_students(d.name)
for stud in students:
make_attendance_records(stud.student, stud.student_name, status[weighted_choice([9,4])], None, d.name, current_date)
@@ -77,7 +77,7 @@ def make_fees():
def make_assessment_plan(date):
for d in range(1,4):
random_group = get_random("Student Group", {"group_based_on": "Course"}, True)
random_group = get_random("Student Group", {"group_based_on": "Course", "disabled": 0}, True)
doc = frappe.new_doc("Assessment Plan")
doc.student_group = random_group.name
doc.course = random_group.course

View File

@@ -4,7 +4,7 @@ We can also send the feedback request to Customer/User without configuring the
Feedback Trigger.
To request a feedback manually go to respective document e.g. Sales Order, Issue etc.
and click on Ask a Feedback option in Menu.
and click on Request Feedback option in Menu.
<img class="screenshot" alt="Setting Condition" src="/docs/assets/img/setup/feedback/manual-feedback-request-option.png">

View File

@@ -88,16 +88,14 @@ def make_attendance_records(student, student_name, status, course_schedule=None,
:param course_schedule: Course Schedule.
:param status: Status (Present/Absent)
"""
student_attendance_list = frappe.get_list("Student Attendance", fields = ['name'], filters = {
student_attendance = frappe.get_doc({
"doctype": "Student Attendance",
"student": student,
"course_schedule": course_schedule,
"student_group": student_group,
"date": date
})
if student_attendance_list:
student_attendance = frappe.get_doc("Student Attendance", student_attendance_list[0])
else:
if not student_attendance:
student_attendance = frappe.new_doc("Student Attendance")
student_attendance.student = student
student_attendance.student_name = student_name

View File

@@ -1,7 +1,7 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_import": 1,
"allow_rename": 0,
"autoname": "RES.######",
"beta": 0,
@@ -662,7 +662,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-01-09 14:14:30.090317",
"modified": "2018-08-20 11:21:19.248393",
"modified_by": "Administrator",
"module": "Education",
"name": "Assessment Result",

View File

@@ -195,6 +195,38 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"description": "If enabled, field Academic Term will be Mandatory in Program Enrollment Tool.",
"fieldname": "academic_term_reqd",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Make Academic Term Mandatory",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -267,7 +299,7 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
"modified": "2017-11-28 15:45:30.324324",
"modified": "2018-07-26 04:43:35.406690",
"modified_by": "Administrator",
"module": "Education",
"name": "Education Settings",

View File

@@ -31,7 +31,8 @@ frappe.ui.form.on('Fee Schedule', {
return {
"program": frm.doc.program,
"academic_term": frm.doc.academic_term,
"academic_year": frm.doc.academic_year
"academic_year": frm.doc.academic_year,
"disabled": 0
};
});
frappe.realtime.on("fee_schedule_progress", function(data) {

View File

@@ -671,7 +671,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2017-12-27 10:59:36.838548",
"modified": "2018-07-26 04:44:03.781418",
"modified_by": "Administrator",
"module": "Education",
"name": "Program Enrollment",

View File

@@ -26,7 +26,6 @@ class ProgramEnrollment(Document):
"student": self.student,
"program": self.program,
"academic_year": self.academic_year,
"academic_term": self.academic_term,
"docstatus": ("<", 2),
"name": ("!=", self.name)
})
@@ -86,7 +85,6 @@ def get_program_courses(doctype, txt, searchfield, start, page_len, filters):
"program": filters['program']
})
@frappe.whitelist()
def get_students(doctype, txt, searchfield, start, page_len, filters):
if not filters.get("academic_term"):

View File

@@ -5,6 +5,9 @@ frappe.ui.form.on("Program Enrollment Tool", {
setup: function(frm) {
frm.add_fetch("student", "title", "student_name");
frm.add_fetch("student_applicant", "title", "student_name");
if(frm.doc.__onload && frm.doc.__onload.academic_term_reqd) {
frm.toggle_reqd("academic_term", true);
}
},
"refresh": function(frm) {

View File

@@ -513,7 +513,7 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
"modified": "2018-01-02 11:59:40.230689",
"modified": "2018-07-26 04:44:13.232146",
"modified_by": "Administrator",
"module": "Education",
"name": "Program Enrollment Tool",

View File

@@ -7,8 +7,13 @@ import frappe
from frappe import _
from frappe.model.document import Document
from erpnext.education.api import enroll_student
from frappe.utils import cint
class ProgramEnrollmentTool(Document):
def onload(self):
academic_term_reqd = cint(frappe.db.get_single_value('Education Settings', 'academic_term_reqd'))
self.set_onload("academic_term_reqd", academic_term_reqd)
def get_students(self):
students = []
if not self.get_students_from:

View File

@@ -3,7 +3,7 @@
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 0,
"autoname": "SA.######",
"autoname": "",
"beta": 0,
"creation": "2015-11-05 15:20:23.045996",
"custom": 0,
@@ -40,7 +40,7 @@
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"search_index": 1,
"set_only_once": 0,
"unique": 0
},
@@ -101,7 +101,7 @@
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"search_index": 1,
"set_only_once": 0,
"unique": 0
},
@@ -239,7 +239,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-11-10 19:09:51.041960",
"modified": "2018-07-27 10:48:22.301531",
"modified_by": "Administrator",
"module": "Education",
"name": "Student Attendance",

View File

@@ -7,7 +7,8 @@ frappe.ui.form.on('Student Attendance Tool', {
frm.set_query("student_group", function() {
return {
"filters": {
"group_based_on": frm.doc.group_based_on
"group_based_on": frm.doc.group_based_on,
"disabled": 0
}
};
});

View File

@@ -82,36 +82,39 @@ frappe.ui.form.on("Student Group", {
max_roll_no = d.group_roll_number;
}
});
frappe.call({
method: "erpnext.education.doctype.student_group.student_group.get_students",
args: {
"academic_year": frm.doc.academic_year,
"academic_term": frm.doc.academic_term,
"group_based_on": frm.doc.group_based_on,
"program": frm.doc.program,
"batch" : frm.doc.batch,
"course": frm.doc.course
},
callback: function(r) {
if(r.message) {
$.each(r.message, function(i, d) {
if(!in_list(student_list, d.student)) {
var s = frm.add_child("students");
s.student = d.student;
s.student_name = d.student_name;
if (d.active === 0) {
s.active = 0;
if(frm.doc.academic_year) {
frappe.call({
method: "erpnext.education.doctype.student_group.student_group.get_students",
args: {
"academic_year": frm.doc.academic_year,
"academic_term": frm.doc.academic_term,
"group_based_on": frm.doc.group_based_on,
"program": frm.doc.program,
"batch" : frm.doc.batch,
"course": frm.doc.course
},
callback: function(r) {
if(r.message) {
$.each(r.message, function(i, d) {
if(!in_list(student_list, d.student)) {
var s = frm.add_child("students");
s.student = d.student;
s.student_name = d.student_name;
if (d.active === 0) {
s.active = 0;
}
s.group_roll_number = ++max_roll_no;
}
s.group_roll_number = ++max_roll_no;
}
});
refresh_field("students");
frm.save();
} else {
frappe.msgprint(__("Student Group is already updated."))
});
refresh_field("students");
frm.save();
} else {
frappe.msgprint(__("Student Group is already updated."))
}
}
}
})
})
}
} else {
frappe.msgprint(__("Select students manually for the Activity based Group"));
}

View File

@@ -293,6 +293,37 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"fieldname": "disabled",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Disabled",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -459,7 +490,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2017-11-10 19:09:37.370864",
"modified": "2018-07-26 04:17:10.836912",
"modified_by": "Administrator",
"module": "Education",
"name": "Student Group",

View File

@@ -33,7 +33,7 @@ class StudentGroup(Document):
program_enrollment = get_program_enrollment(self.academic_year, self.academic_term, self.program, self.batch, self.course)
students = [d.student for d in program_enrollment] if program_enrollment else []
for d in self.students:
if not frappe.db.get_value("Student", d.student, "enabled") and d.active:
if not frappe.db.get_value("Student", d.student, "enabled") and d.active and not self.disabled:
frappe.throw(_("{0} - {1} is inactive student".format(d.group_roll_number, d.student_name)))
if (self.group_based_on == "Batch") and cint(frappe.defaults.get_defaults().validate_batch)\

View File

@@ -24,7 +24,7 @@ frappe.ui.form.on('Student Report Generation Tool', {
frm.page.clear_indicator();
frm.page.set_primary_action(__('Print Report Card'), () => {
let url = "/api/method/erpnext.education.doctype.student_report_generation_tool.student_report_generation_tool.preview_report_card";
open_url_post(url, frm.doc, true);
open_url_post(url, {"doc": frm.doc}, true);
});
},

View File

@@ -3,7 +3,7 @@
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
import frappe, json
from frappe.model.document import Document
from erpnext.education.api import get_grade
from frappe.utils.pdf import get_pdf
@@ -16,8 +16,8 @@ class StudentReportGenerationTool(Document):
@frappe.whitelist()
def preview_report_card(**kwargs):
doc = frappe._dict(**kwargs)
def preview_report_card(doc):
doc = frappe._dict(json.loads(doc))
doc.students = [doc.student]
if not (doc.student_name and doc.student_batch):
program_enrollment = frappe.get_all("Program Enrollment", fields=["student_batch_name", "student_name"],
@@ -33,7 +33,7 @@ def preview_report_card(**kwargs):
course_criteria = get_courses_criteria(courses)
# get the assessment group as per the user selection
if int(doc.include_all_assessment):
if doc.include_all_assessment:
assessment_groups = get_child_assessment_groups(doc.assessment_group)
else:
assessment_groups = [doc.assessment_group]
@@ -55,7 +55,7 @@ def preview_report_card(**kwargs):
"assessment_groups": assessment_groups,
"course_criteria": course_criteria,
"letterhead": letterhead.content,
"add_letterhead": int(doc.add_letterhead) if int(doc.add_letterhead) else 0
"add_letterhead": doc.add_letterhead if doc.add_letterhead else 0
})
final_template = frappe.render_template(base_template_path, {"body": html, "title": "Report Card"})

View File

@@ -99,7 +99,7 @@ def get_guardian_map(student_list):
def get_student_roll_no(academic_year, program, batch):
student_group = frappe.get_all("Student Group",
filters={"academic_year":academic_year, "program":program, "batch":batch})
filters={"academic_year":academic_year, "program":program, "batch":batch, "disabled": 0})
if student_group:
roll_no_dict = dict(frappe.db.sql('''select student, group_roll_number from `tabStudent Group Student` where parent=%s''',
(student_group[0].name)))

View File

@@ -73,6 +73,7 @@ def get_attendance_list(from_date, to_date, student_group, students_list):
return att_map
def get_students_with_leave_application(from_date, to_date, students_list):
if not students_list: return
leave_applications = frappe.db.sql("""
select student, from_date, to_date
from `tabStudent Leave Application`

View File

@@ -6,7 +6,7 @@ from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils import getdate
from frappe.utils import getdate, cstr
import json
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account, get_income_account
@@ -113,9 +113,11 @@ def insert_consultation_to_medical_record(doc):
def update_consultation_to_medical_record(consultation):
medical_record_id = frappe.db.sql("select name from `tabPatient Medical Record` where reference_name=%s", (consultation.name))
if(medical_record_id[0][0]):
if medical_record_id and medical_record_id[0][0]:
subject = set_subject_field(consultation)
frappe.db.set_value("Patient Medical Record", medical_record_id[0][0], "subject", subject)
else:
insert_consultation_to_medical_record(consultation)
def delete_medical_record(consultation):
frappe.db.sql("""delete from `tabPatient Medical Record` where reference_name = %s""", (consultation.name))
@@ -123,7 +125,7 @@ def delete_medical_record(consultation):
def set_subject_field(consultation):
subject = "No Diagnosis "
if(consultation.diagnosis):
subject = "Diagnosis: \n"+ str(consultation.diagnosis)+". "
subject = "Diagnosis: \n"+ cstr(consultation.diagnosis)+". "
if(consultation.drug_prescription):
subject +="\nDrug(s) Prescribed. "
if(consultation.test_prescription):

View File

@@ -6,7 +6,7 @@ from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
import json
from frappe.utils import getdate
from frappe.utils import getdate, cstr
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account
from frappe import _
@@ -228,9 +228,9 @@ def get_employee_by_user_id(user_id):
return employee
def insert_lab_test_to_medical_record(doc):
subject = str(doc.test_name)
subject = cstr(doc.test_name)
if(doc.test_comment):
subject += ", \n"+str(doc.test_comment)
subject += ", \n"+ cstr(doc.test_comment)
medical_record = frappe.new_doc("Patient Medical Record")
medical_record.patient = doc.patient
medical_record.subject = subject
@@ -244,7 +244,7 @@ def insert_lab_test_to_medical_record(doc):
def delete_lab_test_from_medical_record(self):
medical_record_id = frappe.db.sql("select name from `tabPatient Medical Record` where reference_name=%s",(self.name))
if(medical_record_id[0][0]):
if medical_record_id and medical_record_id[0][0]:
frappe.delete_doc("Patient Medical Record", medical_record_id[0][0])
def create_item_line(test_code, sales_invoice):

View File

@@ -34,7 +34,7 @@ class LabTestTemplate(Document):
# remove template refernce from item and disable item
if(self.item):
try:
frappe.delete_doc("Item",self.item)
frappe.delete_doc("Item",self.item, force=True)
except Exception:
frappe.throw("""Not permitted. Please disable the Test Template""")

View File

@@ -111,6 +111,7 @@ frappe.ui.form.on('Patient Appointment', {
frm.set_value('appointment_time', selected_slot);
frm.set_value('duration', data.time_per_appointment);
d.hide();
frm.enable_save();
frm.save();
}
});

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