Compare commits

...

350 Commits

Author SHA1 Message Date
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
Nabin Hait
f92fcdbac4 Merge branch 'hotfix' 2018-04-06 15:06:09 +05:30
Nabin Hait
1ff9e0432a bumped to version 10.1.20 2018-04-06 15:36:09 +06:00
rohitwaghchaure
c0f149a3be [Fix] Delivery notification for delivery trip (#13543) 2018-04-06 14:26:26 +05:30
rohitwaghchaure
2ae6cfda5f [Fix] Item variant details report (#13545) 2018-04-06 11:49:04 +05:30
rohitwaghchaure
22d9f0a4aa [Fix] Bin not deleted on delete of an item (#13539) 2018-04-06 10:29:07 +05:30
rohitwaghchaure
aa7cddef5c Merge pull request #13511 from rohitwaghchaure/table_styling
[Fix] Width and margin for account receivable pdc print format
2018-04-04 16:34:21 +05:30
Rohit Waghchaure
3d2b3d37d4 [Fix] Width and margin for account receivable pdc print format 2018-04-04 16:01:33 +05:30
Nabin Hait
821222653b Merge branch 'hotfix' 2018-04-04 11:26:19 +05:30
Nabin Hait
adddb15380 bumped to version 10.1.19 2018-04-04 11:56:19 +06:00
Nabin Hait
5fd79f7f77 Update stock_ledger.py 2018-04-04 11:20:16 +05:30
Vishal Dhayagude
2505c74d64 Place of Supply set on save Delivery Note if Customer Address Present (#13492) 2018-04-04 11:05:21 +05:30
Rushabh Mehta
d5f9ebd008 [optimize] item queries (#13480) 2018-04-02 23:37:33 +05:30
Shreya Shah
d021e45301 exclude current doc while validating (#13450) 2018-04-02 10:43:19 +05:30
Zarrar
e9ca5e81d2 hide add_child for root node (#13444) 2018-04-02 10:40:39 +05:30
Manas Solanki
a7f5589564 fix for the update button in the sales invoice (#13435) 2018-04-02 10:32:00 +05:30
Shreya Shah
a8df73c263 typo in landed cost voucher doc (#13472) 2018-04-02 10:16:27 +05:30
rohitwaghchaure
40a5a3063c [Fix] Allow zero valuation rate if previous sle has zero valuation rate (#13432) 2018-04-02 10:14:49 +05:30
Shreya Shah
d17c24f969 set query in payment account (#13446) 2018-04-02 10:13:48 +05:30
Manas Solanki
0289ad285f fix the route filters and payment account (#13447) 2018-04-02 10:13:22 +05:30
Shreya Shah
562227db8f db escape as single quote in address causes error (#13451) 2018-04-02 10:12:37 +05:30
Achilles Rasquinha
9c1cac80fe Merge pull request #13445 from shreyashah115/typo-in-payroll
Typo in Payroll Entry
2018-04-01 10:29:16 +05:30
Gaurav Naik
03016e5000 Exploded view for BOM Stock Report (#12506)
* Multilevel BOM Stock Report prototype

* Rechristened multilevel to exploded view

* Removed trailing whitespace in line 16. Replaced spaces with tabs for indentation

* Used BOM Explosion item in query for exploded view

* Removed trailing whitespaces for Codacy compliance
2018-03-30 13:03:19 +05:30
Shreya
9240eaa0a6 typo for accrual journal entry 2018-03-30 12:19:11 +05:30
Manas Solanki
618940b5c9 Merge pull request #13433 from manassolanki/fix-pe
minor fix for the program enrollment tool
2018-03-29 16:37:54 +05:30
Manas Solanki
ccf2b7b08b minor fix for the program enrollment tool 2018-03-29 16:36:59 +05:30
Nabin Hait
1e989b35ad Merge branch 'hotfix' 2018-03-29 13:53:00 +05:30
Nabin Hait
cae2723920 bumped to version 10.1.18 2018-03-29 14:23:00 +06:00
rohitwaghchaure
badc855400 [Fix] BOM validation issue for scrap item (#13429) 2018-03-29 13:48:38 +05:30
Manas Solanki
a4502c4f6b Merge pull request #13430 from codingCoffee/child_doc_perm_fix
Permisssion fixes for child table
2018-03-29 13:27:08 +05:30
Manas Solanki
1f02c62339 Merge pull request #13431 from manassolanki/fix-22
fix the item varint details
2018-03-29 13:26:14 +05:30
Manas Solanki
ef770b593a fix the item varint details 2018-03-29 13:25:00 +05:30
Manas Solanki
a9c90c96a9 Merge pull request #13428 from frappe/manassolanki-patch-3
Update get_item_details.py
2018-03-29 13:16:40 +05:30
Ameya Shenoy
c5d222253a Permisssion fixes for child table
Related to commit 595929eb2432140a27dc262d4d78aca4ec5455c3
frappe.client.[get_list, get, get_value] when called on child table
needs parent as an argument or it throws an error by default
2018-03-29 13:16:08 +05:30
Manas Solanki
94769d81a8 Update get_item_details.py 2018-03-29 11:15:05 +05:30
rohitwaghchaure
edd63a178f Merge pull request #13418 from rohitwaghchaure/pdf_and_alignment_issue
[Fix] Alignment and date issue in PDC report
2018-03-28 17:17:37 +05:30
Rohit Waghchaure
ace68cd283 [Fix] Alignment and date issue in PDC report 2018-03-28 15:53:29 +05:30
Nabin Hait
d3bd151c30 Merge branch 'hotfix' 2018-03-28 15:51:16 +05:30
Nabin Hait
0794816527 bumped to version 10.1.17 2018-03-28 16:21:16 +06:00
Nabin Hait
7041a45294 Update fix_reserved_qty_for_sub_contract.py 2018-03-28 15:50:14 +05:30
Nabin Hait
a6746407e5 Fixed waiting qty in item dashboard data 2018-03-28 11:16:12 +05:30
Nabin Hait
e3407083fe Merge branch 'hotfix' 2018-03-28 10:40:12 +05:30
Nabin Hait
63e40b52af bumped to version 10.1.16 2018-03-28 11:10:12 +06:00
Nabin Hait
2e203e53c6 Update fix_reserved_qty_for_sub_contract.py 2018-03-28 10:38:55 +05:30
Shreya Shah
c0201877dd fixed column fieldnames for translations (#13406) 2018-03-27 18:45:42 +05:30
Nabin Hait
745292ce98 Merge branch 'hotfix' 2018-03-27 14:22:28 +05:30
Nabin Hait
00279f27f3 bumped to version 10.1.15 2018-03-27 14:52:27 +06:00
Nabin Hait
f620dae8ca Null issue fixed in gstr reports 2018-03-27 14:15:36 +05:30
Nabin Hait
9d7fe1f7cd Indicator fix for stock entry item table 2018-03-27 13:30:11 +05:30
Shreya Shah
ba4f32be5c set default warehouse instead of product bundle's warehouse for packed_items in delivery note (#13398) 2018-03-27 11:32:10 +05:30
rohitwaghchaure
85f63a3866 [Fix] Showing to bill even if per deliverd in sales order is 99.9996 (#13392) 2018-03-27 11:31:44 +05:30
Shreya Shah
149f7ee875 [Fix] General Ledger Report (#13374)
* error fix if party_type = student or shareholder

* clear party filter when party_type changes to avoid error throw

* dict with values of party_name in utils.js

* fetch party_name from erpnext.utils.get_party_name

* Update general_ledger.py
2018-03-27 11:29:25 +05:30
rohitwaghchaure
c9a1eb1081 [Fix] Not able to delete row in modal table (#13377) 2018-03-27 11:26:43 +05:30
rohitwaghchaure
2e560cb25d [Fix] Same serial no returned two times (#13378) 2018-03-27 11:24:50 +05:30
Nabin Hait
651b612909 Fixed logic for reserved qty for subcontract and production and written a patch (#13396)
* Fixed logic for reserved qty for subcontract and production and written a patch

* repost reserved qty for filtered bins
2018-03-27 11:24:20 +05:30
Manas Solanki
398eac3f4c message in the program enrollment tool (#13393) 2018-03-27 11:21:47 +05:30
Shreya Shah
f3025f1596 operation time in grid view (#13400) 2018-03-27 10:34:05 +05:30
Nabin Hait
0712013960 Merge branch 'hotfix' 2018-03-23 16:05:06 +05:30
Nabin Hait
3fdda7a9b7 bumped to version 10.1.14 2018-03-23 16:35:06 +06:00
Shreya Shah
9bcadf8126 Tax Id in some reports and print formats (#13373)
* tax-id in sales and purchase registers

* tax-id in general ledger print_format

* tax-id in accounts payable

* tax-id in accounts receivable
2018-03-23 15:04:37 +05:30
rohitwaghchaure
492de67d7b Added consumed material cost in project (#13365) 2018-03-23 15:02:04 +05:30
Nabin Hait
80a9f523d5 Minor fix AR/AP summary report 2018-03-23 13:02:27 +05:30
Nabin Hait
e3f0412570 Pass doc while autonaming item 2018-03-22 12:13:21 +05:30
rohitwaghchaure
23fa8893a8 [Fix] Division by zero issue (#13362) 2018-03-22 11:16:00 +05:30
Manas Solanki
a3714e1678 Merge pull request #13360 from frappe/manassolanki-patch-3
Update update_project_in_sle.py
2018-03-21 18:25:26 +05:30
Manas Solanki
0f6c35d63f Update update_project_in_sle.py 2018-03-21 18:24:45 +05:30
rohitwaghchaure
93779c21a7 [Fix] Project not set in the stock ledger entry (#13357) 2018-03-21 17:52:41 +05:30
Manas Solanki
e010ddf65f Student Report Card (#13346)
* finalise the assessment report

* minor fixes for button

* fix the travis and codacy
2018-03-21 17:50:42 +05:30
Zarrar
969c8aaf52 [Enhance] Fetch Customer's Item code based on Customer Name or Customer Group (#13198)
* customer code can be assigned based on customer group

* improvise customer group selection

* requested changes made
2018-03-21 11:17:49 +05:30
Manas Solanki
c711445b91 add the student as party type (#13348) 2018-03-21 10:12:27 +05:30
rohitwaghchaure
2b88ac948e [Fix] Special character issue (#13350) 2018-03-21 10:04:47 +05:30
Siddhi Sawant
c672530210 [hotfix] Added 'Paid Amount' and 'Change Amount' in POS print formats (#13316)
* Added 'Paid Amount' and 'Change Amount' in GST POS Invoice and POS Invoice print formats

* Update gst_pos_invoice.json

Updated its 'disabled' property.

* Update pos_invoice.json

Updated its 'disabled' property.

* Shows change amount only if it exists

* Updated disable property of print formats
2018-03-20 14:31:14 +05:30
Zarrar
c5b061834b doctype dropdown rectify, validate series is set (#13305) 2018-03-20 13:06:18 +05:30
Nabin Hait
8a8966ce9b minor fix 2018-03-20 11:19:57 +05:30
Achilles Rasquinha
54f3a0f7c6 Merge pull request #13333 from achillesrasquinha/hotfixes
Check Set Sales Target Item exists in User Slides
2018-03-19 22:23:11 +05:30
Achilles Rasquinha
ecc4fdd3ef Check Set Sales Target Item exists in User Slides 2018-03-19 22:21:45 +05:30
Achilles Rasquinha
60da37b502 Merge pull request #13329 from shreyashah115/travis-fix
[Fix] Travis
2018-03-19 19:10:21 +05:30
Saurabh
2777fd4332 [fix] validate minimum transaction amount in Payment Request for selected payment gateway (#13328) 2018-03-19 18:29:01 +05:30
Shreya
9602bf4ba3 patch fix 2018-03-19 18:17:54 +05:30
Shreya
5042dd32da undefined args error 2018-03-19 17:45:39 +05:30
Shreya
4d347b1ca0 travis fix 2018-03-19 17:31:19 +05:30
Achilles Rasquinha
3d85951c1f Merge pull request #13304 from achillesrasquinha/hotfix-hub
[HOTFIX] Hub Domain Change
2018-03-19 11:54:13 +05:30
Manas Solanki
7b91042ae6 Merge pull request #13310 from manassolanki/student-report-card
addition of student report card generation tool
2018-03-16 02:00:07 +05:30
Manas Solanki
633a39144d addition of student report card generation tool 2018-03-16 01:57:45 +05:30
Achilles Rasquinha
94b41ea4f6 removed debugging 2018-03-15 12:53:22 +05:30
Achilles Rasquinha
d8f7de9946 fixed patch for hub 2018-03-15 12:48:32 +05:30
Nabin Hait
b2d318ec48 Merge branch 'hotfix' 2018-03-15 12:38:41 +05:30
Nabin Hait
60200eaf0d bumped to version 10.1.13 2018-03-15 13:08:41 +06:00
Nabin Hait
1e4cfb4bf5 Fixes in setting po nos manually in sales invoice 2018-03-15 12:27:24 +05:30
Nabin Hait
70abac0061 Get territory from sales invoice 2018-03-15 12:19:16 +05:30
Nabin Hait
d7f32e492f Merge branch 'hotfix' 2018-03-14 13:33:36 +05:30
Nabin Hait
6c09297bcd bumped to version 10.1.12 2018-03-14 14:03:36 +06:00
Nabin Hait
363cedde76 Fixed minor issue 2018-03-14 13:32:14 +05:30
Nabin Hait
f5ad339cae Merge branch 'hotfix' 2018-03-13 18:13:43 +05:30
Nabin Hait
c8c733bc54 bumped to version 10.1.11 2018-03-13 18:43:42 +06:00
Shreya Shah
7acc8cb747 fix else condition (#13295) 2018-03-13 18:12:19 +05:30
Nabin Hait
9a398b4742 Merge branch 'hotfix' 2018-03-13 17:11:49 +05:30
Nabin Hait
56882033bf bumped to version 10.1.10 2018-03-13 17:41:49 +06:00
Nabin Hait
74c817e7f9 Update update_reserved_qty_for_purchase_order.py 2018-03-13 17:10:14 +05:30
Nabin Hait
d98a6d81eb Merge branch 'hotfix' 2018-03-13 16:14:02 +05:30
Nabin Hait
baac05955b bumped to version 10.1.9 2018-03-13 16:44:02 +06:00
Nabin Hait
89346967da Reverted #13259 (#13291) 2018-03-13 16:01:11 +05:30
Nabin Hait
97e890d0b3 Fix in unallocated amount calc in payment entry (#13288) 2018-03-13 15:57:34 +05:30
Ameya Shenoy
95763bc233 Purchase Order fixes (#13287)
- Reason: If Item Code was changed in Item Master, it didn't used to reflect on the 'Purchase Order Item Supplied' and 'Purchase Reciept Item Supplied'
- Data field in 'Production Order Item Supplied' and 'Production Reciept Item Supplied' converted to Link Field.
2018-03-13 15:51:56 +05:30
Nabin Hait
96f4b22589 Set po nos in DN and SI (#13290) 2018-03-13 15:46:59 +05:30
rohitwaghchaure
13460f023d [Fix] Batch value showing as item value while making batch (#13281) 2018-03-12 17:20:50 +05:30
Nabin Hait
3907eae83f Merge branch 'hotfix' 2018-03-12 15:31:03 +05:30
Nabin Hait
04f50be306 bumped to version 10.1.8 2018-03-12 16:01:03 +06:00
Ameya Shenoy
b34ab7549a fixed subject to task_name (#13278) 2018-03-12 15:24:01 +05:30
Shreya Shah
aa54d934b8 make stock qty negative (#13276) 2018-03-12 15:23:28 +05:30
Nabin Hait
2c7a6e6b43 Reserve for subcontracting (#13195)
* [fix] #8427

* review comments changes

* Validation for reserved warhouse

* code improvements

* alignment

* test case

* message changes

* default warehouse / remove validation / change sql

* fix

* patch

* Fixed merge conflict

* Fixes and cleanups of reserve qty for subcontracting

* set from_warehouse only if purchase_order and purpose found (#12398)

* [HotFix] Validation issue for subcontract stock entry (#12127)

* [Fix] Validation issue for subcontract stock entry

* Update stock_entry.py

* Fixes and cleanups of reserve qty for subcontracting

* patch fixed

* Reload bin in patch

* [fix] set source warehouse in stock entry for manufacture

* [fix] #8540

* code alignment

* code alignment

* Move target warehouse validation to submit

* validation code improvement

* code changes for single stock entry

* validation fix

* call make_rm_stock_entry

* remove old stock entry method/rewrite test case

* Don't set bom_no against raw materials while trasferring items for sub-contracting

* minor fix
2018-03-12 14:12:12 +05:30
Shreya Shah
58797481f0 uncheck report hide (#13256) 2018-03-12 13:08:01 +05:30
rohitwaghchaure
12aa4265ff Don't allow to set negative quantity if transaction is not return entry (#13255) 2018-03-12 11:20:30 +05:30
Shreya Shah
69d9f51dbb if price list not found, set default selling/ buying price list from settings (#13259) 2018-03-12 11:15:49 +05:30
Nabin Hait
3dea6589d7 Merge branch 'hotfix' 2018-03-09 16:38:51 +05:30
Nabin Hait
096d136460 bumped to version 10.1.7 2018-03-09 17:08:50 +06:00
Nabin Hait
c3889d85a1 Update shopping_cart.js 2018-03-09 16:28:25 +05:30
Nabin Hait
052333ea63 subctracting stock entry should also be considered as consumed qty 2018-03-09 14:30:32 +05:30
Shreya Shah
aadd30d194 fetch delivery date on add-row only if item_code exists (#13250) 2018-03-09 12:19:35 +05:30
Harsh Patel
22e6f8d4c2 Fixes for #13071 (#13234) 2018-03-08 16:23:59 +05:30
rohitwaghchaure
acd3479269 Bank POS transactions in bank reconciliation (#13225) 2018-03-08 16:22:39 +05:30
rohitwaghchaure
a32e57ae82 [Fix] Discount in offline POS is enabled even is it's disabled in POS Profile (#13233) 2018-03-08 16:21:13 +05:30
Ranjith Kurungadam
a3a63177a1 fix- cannot cancel consultation, remove updating age (#13226) 2018-03-08 16:20:22 +05:30
tundebabzy
1643cce479 fetch journal entry details (#13218) 2018-03-08 11:17:17 +05:30
Manas Solanki
bb42e3b411 Merge pull request #13214 from manassolanki/assessment-report-fix
minor fix for key error in assessment reports
2018-03-07 16:30:35 +05:30
Manas Solanki
586e9400b1 minor fix for key error 2018-03-07 16:28:21 +05:30
Vishal Dhayagude
668ec25d19 Allow Item variant Rename (#13161)
* [WIP] Item varient rename

* [wip] Item Variant

* [fix] Item Varient Rename

* [fix] Item Attribution Rename

* removed unwanted code
2018-03-07 15:31:08 +05:30
Nabin Hait
f0543a9765 Merge branch 'hotfix' 2018-03-07 13:09:06 +05:30
Nabin Hait
36b4faab48 bumped to version 10.1.6 2018-03-07 13:39:05 +06:00
Saurabh
2b59a851c4 Merge pull request #13166 from saurabh6790/patches_fixes
[fix] use join instead of subquery
2018-03-07 12:59:03 +05:30
Manas Solanki
857d4f7a0b Merge pull request #13209 from manassolanki/guardian-fix
allow renaming of the guardian
2018-03-07 12:53:40 +05:30
Manas Solanki
12d7bfb658 allow renaming of the guardian 2018-03-07 12:52:31 +05:30
Saurabh
ca6e223694 [fix] use join instead of subquery 2018-03-07 12:13:32 +05:30
rohitwaghchaure
343ba85e3a Merge pull request #13203 from saurabh6790/pe_fix
[fix] setup_party_account_field on init
2018-03-07 12:11:46 +05:30
Manas Solanki
16c324f699 Merge pull request #13207 from manassolanki/course-schedule-fix
fix the desktop icon for course schedule
2018-03-07 12:10:36 +05:30
Manas Solanki
1fa992564a fix the desktop icon for course schedule 2018-03-07 12:08:52 +05:30
Saurabh
a65b28772f [fix] setup_party_account_field on init 2018-03-06 18:22:01 +05:30
231 changed files with 4795 additions and 1015 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.5'
__version__ = '10.1.41'
def get_default_company(user=None):
'''Get default company for user'''

View File

@@ -169,10 +169,10 @@ class Account(NestedSet):
# 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)
new_account = get_name_with_number(new_account, self.account_number)
# Validate properties before merging
if merge:
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))

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

@@ -159,6 +159,36 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "include_pos_transactions",
"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": "Include POS Transactions",
"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,
@@ -292,7 +322,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2017-04-21 16:58:26.902732",
"modified": "2018-03-07 18:58:48.658687",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Bank Reconciliation",

View File

@@ -53,10 +53,26 @@ class BankReconciliation(Document):
posting_date ASC, name DESC
""".format(condition),
{"account":self.bank_account, "from":self.from_date, "to":self.to_date}, as_dict=1)
entries = sorted(list(payment_entries)+list(journal_entries),
pos_entries = []
if self.include_pos_transactions:
pos_entries = frappe.db.sql("""
select
"Sales Invoice Payment" as payment_document, sip.name as payment_entry, sip.amount as debit,
si.posting_date, si.debit_to as against_account, sip.clearance_date,
account.account_currency, 0 as credit
from `tabSales Invoice Payment` sip, `tabSales Invoice` si, `tabAccount` account
where
sip.account=%(account)s and si.docstatus=1 and sip.parent = si.name
and account.name = sip.account and si.posting_date >= %(from)s and si.posting_date <= %(to)s {0}
order by
si.posting_date ASC, si.name DESC
""".format(condition),
{"account":self.bank_account, "from":self.from_date, "to":self.to_date}, as_dict=1)
entries = sorted(list(payment_entries)+list(journal_entries+list(pos_entries)),
key=lambda k: k['posting_date'] or getdate(nowdate()))
self.set('payment_entries', [])
self.total_amount = 0.0

View File

@@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
from __future__ import unicode_literals
import unittest
class TestBankReconciliation(unittest.TestCase):
pass

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

@@ -48,5 +48,10 @@ frappe.treeview_settings["Cost Center"] = {
}, __('Budget'));
},
onrender: function(node) {
if(node.is_root){
node.hide_add = true;
}
}
}

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

@@ -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)
@@ -676,30 +680,17 @@ frappe.ui.form.on('Payment Entry', {
function(d) { return flt(d.amount) }));
if(frm.doc.party) {
var party_amount = frm.doc.payment_type=="Receive" ?
frm.doc.paid_amount : frm.doc.received_amount;
var company_currency = frm.doc.company? frappe.get_doc(":Company", frm.doc.company).default_currency: "";
if (frm.doc.party_account_currency == company_currency) {
if(frm.doc.payment_type == "Receive" && frm.doc.total_allocated_amount <= party_amount + total_deductions) {
unallocated_amount = party_amount - (frm.doc.total_allocated_amount - total_deductions);
} else if (frm.doc.payment_type == "Pay" && frm.doc.total_allocated_amount <= party_amount - total_deductions) {
unallocated_amount = party_amount - (frm.doc.total_allocated_amount + total_deductions);
}
} else {
if(frm.doc.payment_type == "Receive"
&& frm.doc.base_total_allocated_amount <= frm.doc.base_received_amount + total_deductions
&& frm.doc.total_allocated_amount < frm.doc.paid_amount) {
unallocated_amount = (frm.doc.base_received_amount + total_deductions
- frm.doc.base_total_allocated_amount) / frm.doc.source_exchange_rate;
} else if (frm.doc.payment_type == "Pay"
&& frm.doc.base_total_allocated_amount < frm.doc.base_paid_amount - total_deductions
&& frm.doc.total_allocated_amount < frm.doc.received_amount) {
unallocated_amount = (frm.doc.base_paid_amount - (total_deductions
+ frm.doc.base_total_allocated_amount)) / frm.doc.target_exchange_rate;
}
if(frm.doc.payment_type == "Receive"
&& frm.doc.base_total_allocated_amount < frm.doc.base_received_amount + total_deductions
&& frm.doc.total_allocated_amount < frm.doc.paid_amount + (total_deductions / frm.doc.source_exchange_rate)) {
unallocated_amount = (frm.doc.base_received_amount + total_deductions
- frm.doc.base_total_allocated_amount) / frm.doc.source_exchange_rate;
} else if (frm.doc.payment_type == "Pay"
&& frm.doc.base_total_allocated_amount < frm.doc.base_paid_amount - total_deductions
&& frm.doc.total_allocated_amount < frm.doc.received_amount + (total_deductions / frm.doc.target_exchange_rate)) {
unallocated_amount = (frm.doc.base_paid_amount - (total_deductions
+ frm.doc.base_total_allocated_amount)) / frm.doc.target_exchange_rate;
}
}
frm.set_value("unallocated_amount", unallocated_amount);
frm.trigger("set_difference_amount");
@@ -828,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

@@ -20,6 +20,11 @@ class InvalidPaymentEntry(ValidationError):
class PaymentEntry(AccountsController):
def __init__(self, *args, **kwargs):
super(PaymentEntry, self).__init__(*args, **kwargs)
if not self.is_new():
self.setup_party_account_field()
def setup_party_account_field(self):
self.party_account_field = None
self.party_account = None
@@ -289,27 +294,16 @@ class PaymentEntry(AccountsController):
self.unallocated_amount = 0
if self.party:
total_deductions = sum([flt(d.amount) for d in self.get("deductions")])
if self.party_account_currency == self.company_currency:
if self.payment_type == "Receive" \
and self.total_allocated_amount <= self.paid_amount + total_deductions:
self.unallocated_amount = self.paid_amount - \
(self.total_allocated_amount - total_deductions)
elif self.payment_type == "Pay" \
and self.total_allocated_amount <= self.received_amount - total_deductions:
self.unallocated_amount = self.received_amount - \
(self.total_allocated_amount + total_deductions)
else:
if self.payment_type == "Receive" \
and self.base_total_allocated_amount <= self.base_received_amount + total_deductions \
and self.total_allocated_amount < self.paid_amount:
self.unallocated_amount = (self.base_received_amount + total_deductions -
self.base_total_allocated_amount) / self.source_exchange_rate
elif self.payment_type == "Pay" \
and self.base_total_allocated_amount < (self.base_paid_amount - total_deductions) \
and self.total_allocated_amount < self.received_amount:
self.unallocated_amount = (self.base_paid_amount - (total_deductions +
self.base_total_allocated_amount)) / self.target_exchange_rate
if self.payment_type == "Receive" \
and self.base_total_allocated_amount < self.base_received_amount + total_deductions \
and self.total_allocated_amount < self.paid_amount + (total_deductions / self.source_exchange_rate):
self.unallocated_amount = (self.base_received_amount + total_deductions -
self.base_total_allocated_amount) / self.source_exchange_rate
elif self.payment_type == "Pay" \
and self.base_total_allocated_amount < (self.base_paid_amount - total_deductions) \
and self.total_allocated_amount < self.received_amount + (total_deductions / self.target_exchange_rate):
self.unallocated_amount = (self.base_paid_amount - (total_deductions +
self.base_total_allocated_amount)) / self.target_exchange_rate
def set_difference_amount(self):
base_unallocated_amount = flt(self.unallocated_amount) * (flt(self.source_exchange_rate)
@@ -343,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)
@@ -678,6 +673,24 @@ def get_company_defaults(company):
return ret
def get_outstanding_on_journal_entry(name):
res = frappe.db.sql(
'SELECT '
'CASE WHEN party_type IN ("Customer", "Student") '
'THEN ifnull(sum(debit_in_account_currency - credit_in_account_currency), 0) '
'ELSE ifnull(sum(credit_in_account_currency - debit_in_account_currency), 0) '
'END as outstanding_amount '
'FROM `tabGL Entry` WHERE (voucher_no=%s OR against_voucher=%s) '
'AND party_type IS NOT NULL '
'AND party_type != ""',
(name, name), as_dict=1
)
outstanding_amount = res[0].get('outstanding_amount', 0) if res else 0
return outstanding_amount
@frappe.whitelist()
def get_reference_details(reference_doctype, reference_name, party_account_currency):
total_amount = outstanding_amount = exchange_rate = None
@@ -688,6 +701,13 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
total_amount = ref_doc.get("grand_total")
exchange_rate = 1
outstanding_amount = ref_doc.get("outstanding_amount")
elif reference_doctype == "Journal Entry" and ref_doc.docstatus == 1:
total_amount = ref_doc.get("total_amount")
if ref_doc.multi_currency:
exchange_rate = get_exchange_rate(party_account_currency, company_currency, ref_doc.posting_date)
else:
exchange_rate = 1
outstanding_amount = get_outstanding_on_journal_entry(reference_name)
elif reference_doctype != "Journal Entry":
if party_account_currency == company_currency:
if ref_doc.doctype == "Expense Claim":
@@ -705,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:
@@ -749,6 +772,8 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
party_account = doc.receivable_account
elif dt == "Employee Advance":
party_account = doc.advance_account
elif dt == "Expense Claim":
party_account = doc.payable_account
else:
party_account = get_party_account(party_type, doc.get(party_type.lower()), doc.company)

View File

@@ -78,6 +78,9 @@ class PaymentRequest(Document):
controller = get_payment_gateway_controller(self.payment_gateway)
controller.validate_transaction_currency(self.currency)
if hasattr(controller, 'validate_minimum_transaction_amount'):
controller.validate_minimum_transaction_amount(self.currency, self.grand_total)
return controller.get_payment_url(**{
"amount": flt(self.grand_total, self.precision("grand_total")),
"title": data.company.encode("utf-8"),

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
@@ -131,7 +131,7 @@ def get_serial_no_for_item(args):
"name": args.name,
"serial_no": args.serial_no
})
if args.get("parenttype") in ("Sales Invoice", "Delivery Note") and args.stock_qty > 0:
if args.get("parenttype") in ("Sales Invoice", "Delivery Note") and flt(args.stock_qty) > 0:
item_details.serial_no = get_serial_no(args)
return item_details
@@ -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

@@ -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

@@ -350,7 +350,6 @@ class PurchaseInvoice(BuyingController):
self.negative_expense_to_be_booked = 0.0
gl_entries = []
self.make_supplier_gl_entry(gl_entries)
self.make_item_gl_entries(gl_entries)
self.make_tax_gl_entries(gl_entries)
@@ -424,7 +423,10 @@ class PurchaseInvoice(BuyingController):
# sub-contracting warehouse
if flt(item.rm_supp_cost):
supplier_warehouse_account = warehouse_account[self.supplier_warehouse]["name"]
supplier_warehouse_account = warehouse_account[self.supplier_warehouse]["account"]
if not supplier_warehouse_account:
frappe.throw(_("Please set account in Warehouse {0}")
.format(self.supplier_warehouse))
gl_entries.append(self.get_gl_dict({
"account": supplier_warehouse_account,
"against": item.expense_account,

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

@@ -687,12 +687,12 @@
"in_standard_filter": 0,
"label": "Customer's Purchase Order",
"length": 0,
"no_copy": 0,
"no_copy": 1,
"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,
@@ -751,7 +751,7 @@
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
@@ -1459,7 +1459,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_bulk_edit": 1,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -3742,12 +3742,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 +3755,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 +3831,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 +4713,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2018-01-12 15:19:54.711885",
"modified": "2018-07-06 12:09:02.039783",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",

View File

@@ -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)

View File

@@ -227,6 +227,36 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "clearance_date",
"fieldtype": "Date",
"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": "Clearance Date",
"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
}
],
"has_web_view": 0,
@@ -239,7 +269,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2017-07-24 17:25:03.765856",
"modified": "2018-03-07 18:34:39.552769",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Payment",

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

@@ -393,7 +393,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
this.frm = {}
this.frm.doc = this.doc
this.set_transaction_defaults("Customer");
this.frm.doc["allow_user_to_edit_rate"] = this.pos_profile_data["allow_user_to_edit_rate"] ? true : false,
this.frm.doc["allow_user_to_edit_rate"] = this.pos_profile_data["allow_user_to_edit_rate"] ? true : false;
this.frm.doc["allow_user_to_edit_discount"] = this.pos_profile_data["allow_user_to_edit_discount"] ? true : false;
this.wrapper.html(frappe.render_template("pos", this.frm.doc));
this.make_search();
this.make_customer();
@@ -1256,6 +1257,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
$(this.wrapper).find('.selected-item').empty();
if(this.child_doc.length) {
this.child_doc[0]["allow_user_to_edit_rate"] = this.pos_profile_data["allow_user_to_edit_rate"] ? true : false,
this.child_doc[0]["allow_user_to_edit_discount"] = this.pos_profile_data["allow_user_to_edit_discount"] ? true : false;
this.selected_row = $(frappe.render_template("pos_selected_item", this.child_doc[0]))
$(this.wrapper).find('.selected-item').html(this.selected_row)
}
@@ -1683,7 +1685,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
setInterval(function () {
me.freeze_screen = false;
me.sync_sales_invoice()
}, 60000)
}, 180000)
},
sync_sales_invoice: function () {

View File

@@ -4,12 +4,11 @@
from __future__ import unicode_literals
import frappe
import datetime
from frappe import _, msgprint, scrub
from frappe.defaults import get_user_permissions
from frappe.model.utils import get_fetch_values
from frappe.utils import (add_days, getdate, formatdate, get_first_day, date_diff,
add_years, get_timestamp, nowdate, flt, add_months, get_last_day)
from frappe.utils import (add_days, getdate, formatdate, date_diff,
add_years, get_timestamp, nowdate, flt, add_months, get_last_day)
from frappe.contacts.doctype.address.address import (get_address_display,
get_default_address, get_company_address)
from frappe.contacts.doctype.contact.contact import get_contact_details, get_default_contact
@@ -405,10 +404,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

@@ -7,10 +7,10 @@
"docstatus": 0,
"doctype": "Print Format",
"font": "Default",
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{% if doc.company_address_display %}\n\t\t{% set company_address = doc.company_address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t{% if \"GSTIN\" not in company_address %}\n\t\t\t{{ company_address }}\n\t\t\t<b>{{ _(\"GSTIN\") }}:</b>{{ doc.company_gstin }}\n\t\t{% else %}\n\t\t\t{{ company_address.replace(\"GSTIN\", \"<br>GSTIN\") }}\n\t\t{% endif %}\n\t{% endif %}\n\t<br>\n\t<b>{{ doc.select_print_heading or _(\"Invoice\") }}</b><br>\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t{% if doc.grand_total > 50000 %}\n\t\t{% set customer_address = doc.address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t<b>{{ _(\"Customer\") }}:</b><br>\n\t\t{{ doc.customer_name }}<br>\n\t\t{{ customer_address }}\n\t{% endif %}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"40%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.gst_hsn_code -%}\n\t\t\t\t\t<br><b>{{ _(\"HSN/SAC\") }}:</b> {{ item.gst_hsn_code }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t<br><b>{{ _(\"Serial No\") }}:</b> {{ item.serial_no }}\n\t\t\t\t{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.rate }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% else %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% endif %}\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t<tr>\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t</td>\n\t\t\t<tr>\n\t\t {%- endif -%}\n\t\t{%- endfor -%}\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- if doc.rounded_total -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Rounded Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"rounded_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t</tbody>\n</table>\n<p><b>Tax Breakup:</b></p>\n<div style=\"font-size: 8px\">\n\t{{ doc.other_charges_calculation }}\n</div>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>",
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{% if doc.company_address_display %}\n\t\t{% set company_address = doc.company_address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t{% if \"GSTIN\" not in company_address %}\n\t\t\t{{ company_address }}\n\t\t\t<b>{{ _(\"GSTIN\") }}:</b>{{ doc.company_gstin }}\n\t\t{% else %}\n\t\t\t{{ company_address.replace(\"GSTIN\", \"<br>GSTIN\") }}\n\t\t{% endif %}\n\t{% endif %}\n\t<br>\n\t<b>{{ doc.select_print_heading or _(\"Invoice\") }}</b><br>\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t{% if doc.grand_total > 50000 %}\n\t\t{% set customer_address = doc.address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t<b>{{ _(\"Customer\") }}:</b><br>\n\t\t{{ doc.customer_name }}<br>\n\t\t{{ customer_address }}\n\t{% endif %}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"40%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.gst_hsn_code -%}\n\t\t\t\t\t<br><b>{{ _(\"HSN/SAC\") }}:</b> {{ item.gst_hsn_code }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t<br><b>{{ _(\"Serial No\") }}:</b> {{ item.serial_no }}\n\t\t\t\t{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.rate }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% else %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% endif %}\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t<tr>\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t</td>\n\t\t\t<tr>\n\t\t {%- endif -%}\n\t\t{%- endfor -%}\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- if doc.rounded_total -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Rounded Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"rounded_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Paid Amount\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"paid_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t{%- if doc.change_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Change Amount\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"change_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t{%- endif -%}\n\t</tbody>\n</table>\n<p><b>Tax Breakup:</b></p>\n<div style=\"font-size: 8px\">\n\t{{ doc.other_charges_calculation }}\n</div>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>",
"idx": 0,
"line_breaks": 0,
"modified": "2018-01-12 11:19:17.432600",
"modified": "2018-03-20 14:24:08.167930",
"modified_by": "Administrator",
"module": "Accounts",
"name": "GST POS Invoice",

View File

@@ -6,10 +6,10 @@
"doc_type": "Sales Invoice",
"docstatus": 0,
"doctype": "Print Format",
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{{ doc.select_print_heading or _(\"Invoice\") }}<br>\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t<b>{{ _(\"Customer\") }}:</b> {{ doc.customer_name }}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"50%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.get_formatted(\"rate\") }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% else %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% endif %}\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t<tr>\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t</td>\n\t\t\t<tr>\n\t\t {%- endif -%}\n\t\t{%- endfor -%}\n\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- if doc.rounded_total -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Rounded Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"rounded_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t</tbody>\n</table>\n<hr>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>",
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{{ doc.select_print_heading or _(\"Invoice\") }}<br>\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t<b>{{ _(\"Customer\") }}:</b> {{ doc.customer_name }}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"50%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.get_formatted(\"rate\") }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% else %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% endif %}\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t<tr>\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t</td>\n\t\t\t<tr>\n\t\t {%- endif -%}\n\t\t{%- endfor -%}\n\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- if doc.rounded_total -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Rounded Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"rounded_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Paid Amount\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"paid_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- if doc.change_amount -%}\n\t\t\t<tr>\n\t\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t\t<b>{{ _(\"Change Amount\") }}</b>\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"change_amount\") }}\n\t\t\t\t</td>\n\t\t\t</tr>\n\t\t{%- endif -%}\n\t</tbody>\n</table>\n<hr>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>",
"idx": 1,
"line_breaks": 0,
"modified": "2018-01-12 11:18:54.229254",
"modified": "2018-03-20 14:24:12.394354",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Invoice",

View File

@@ -14,7 +14,13 @@ frappe.query_reports["Accounts Payable"] = {
"fieldname":"supplier",
"label": __("Supplier"),
"fieldtype": "Link",
"options": "Supplier"
"options": "Supplier",
on_change: () => {
var supplier = frappe.query_report_filters_by_name.supplier.get_value();
frappe.db.get_value('Supplier', supplier, "tax_id", function(value) {
frappe.query_report_filters_by_name.tax_id.set_value(value["tax_id"]);
});
}
},
{
"fieldname":"report_date",
@@ -52,6 +58,12 @@ frappe.query_reports["Accounts Payable"] = {
"fieldtype": "Int",
"default": "90",
"reqd": 1
},
{
"fieldname":"tax_id",
"label": __("Tax Id"),
"fieldtype": "Data",
"hidden": 1
}
],
onload: function(report) {

View File

@@ -2,17 +2,35 @@
<style>
@media screen {
.print-format {
padding: 8mm;
margin:4mm;
font-size:10px;
padding: 4mm;
font-size: 8.0pt !important;
font-family: Tahoma, sans-serif;
}
}
</style>
{% } %}
<style>
.print-format {
padding: 4mm;
font-size: 8.0pt !important;
font-family: Tahoma, sans-serif;
}
</style>
<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 %}
{% } %}
</h6>
<h5 class="text-center">
{%= __(filters.ageing_based_on) %}
{%= __("Until") %}
@@ -27,7 +45,7 @@
var range4 = report.columns[14].label;
%}
{% if(balance_row) { %}
<table class="table table-bordered table-condensed table-sm small">
<table class="table table-bordered table-condensed">
<caption class="text-right">(Amount in {%= data[0][__("currency")] || "" %})</caption>
<colgroup>
<col style="width: 30mm;">
@@ -86,8 +104,8 @@
<thead>
<tr>
{% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
<th style="width: 10%">{%= __("Date") %}</th>
<th style="width: 15%">{%= __("Ref") %}</th>
<th style="width: 18%">{%= __("Date") %}</th>
<th style="width: 17%">{%= __("Reference") %}</th>
{% if(!filters.show_pdc_in_print) { %}
<th style="width: 20%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
{% } %}
@@ -120,10 +138,15 @@
<tr>
{% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
{% if(data[i][__("Customer")] || data[i][__("Supplier")]) { %}
<td>{%= dateutil.str_to_user(data[i][__("Posting Date")]) %}</td>
<td>{%= data[i][__("Voucher Type")] %}
<br>{%= data[i][__("Voucher No")] %}</td>
{% if(!filters.show_pdc_in_print) { %}
<td>{%= dateutil.str_to_user(data[i]["posting_date"]) %}</td>
<td>
{% if(!filters.show_pdc_in_print) { %}
{%= data[i]["voucher_type"] %}
<br>
{% } %}
{%= data[i]["voucher_no"] %}
</td>
{% if(!filters.show_pdc_in_print) { %}
<td>
{% if(!(filters.customer || filters.supplier)) { %}
{%= data[i][__("Customer")] || data[i][__("Supplier")] %}
@@ -215,4 +238,4 @@
{% } %}
</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

@@ -14,7 +14,14 @@ frappe.query_reports["Accounts Receivable"] = {
"fieldname":"customer",
"label": __("Customer"),
"fieldtype": "Link",
"options": "Customer"
"options": "Customer",
on_change: () => {
var customer = frappe.query_report_filters_by_name.customer.get_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"]);
});
}
},
{
"fieldname":"customer_group",
@@ -69,6 +76,18 @@ frappe.query_reports["Accounts Receivable"] = {
"fieldname":"show_pdc_in_print",
"label": __("Show PDC in Print"),
"fieldtype": "Check",
},
{
"fieldname":"tax_id",
"label": __("Tax Id"),
"fieldtype": "Data",
"hidden": 1
},
{
"fieldname":"customer_name",
"label": __("Customer Name"),
"fieldtype": "Data",
"hidden": 1
}
],

View File

@@ -22,13 +22,35 @@ class ReceivablePayableReport(object):
return columns, data, None, chart
def get_columns(self, party_naming_by, args):
columns = [_("Posting Date") + ":Date:80", _(args.get("party_type")) + ":Link/" + args.get("party_type") + ":200"]
columns = []
columns.append({
"label": _("Posting Date"),
"fieldtype": "Date",
"fieldname": "posting_date",
"width": 90
})
columns += [_(args.get("party_type")) + ":Link/" + args.get("party_type") + ":200"]
if party_naming_by == "Naming Series":
columns += [args.get("party_type") + " Name::110"]
columns += [_("Voucher Type") + "::110", _("Voucher No") + ":Dynamic Link/"+_("Voucher Type")+":120",
_("Due Date") + ":Date:80"]
columns.append({
"label": _("Voucher Type"),
"fieldtype": "Data",
"fieldname": "voucher_type",
"width": 110
})
columns.append({
"label": _("Voucher No"),
"fieldtype": "Dynamic Link",
"fieldname": "voucher_no",
"width": 110,
"options": "voucher_type",
})
columns += [_("Due Date") + ":Date:80"]
if args.get("party_type") == "Supplier":
columns += [_("Bill No") + "::80", _("Bill Date") + ":Date:80"]
@@ -114,7 +136,7 @@ class ReceivablePayableReport(object):
return_entries = self.get_return_entries(args.get("party_type"))
data = []
pdc_details = get_pdc_details(args.get("party_type"))
pdc_details = get_pdc_details(args.get("party_type"), self.filters.report_date)
for gle in self.get_entries_till(self.filters.report_date, args.get("party_type")):
if self.is_receivable_or_payable(gle, dr_or_cr, future_vouchers):
@@ -160,6 +182,7 @@ class ReceivablePayableReport(object):
row.append(company_currency)
pdc = pdc_details.get((gle.voucher_no, gle.party), {})
remaining_balance = outstanding_amount - flt(pdc.get("pdc_amount"))
row += [pdc.get("pdc_date"), pdc.get("pdc_ref"),
flt(pdc.get("pdc_amount")), remaining_balance]
@@ -263,7 +286,10 @@ class ReceivablePayableReport(object):
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):
from `tabPurchase Invoice` where docstatus = 1
union
select name, due_date, bill_no, bill_date from `tabJournal Entry`
where docstatus = 1 and bill_no is not NULL""", as_dict=1):
voucher_details.setdefault(pi.name, pi)
return voucher_details
@@ -376,7 +402,7 @@ def get_ageing_data(first_range, second_range, third_range, age_as_on, entry_dat
return [age] + outstanding_range
def get_pdc_details(party_type):
def get_pdc_details(party_type, report_date):
pdc_details = frappe._dict()
for pdc in frappe.db.sql("""
@@ -389,13 +415,14 @@ def get_pdc_details(party_type):
on
(pref.parent = pent.name)
where
pent.docstatus < 2 and pent.reference_date >= pent.posting_date
pent.docstatus < 2 and pent.reference_date >= %s
and pent.party_type = %s
group by pent.party, pref.reference_name""", party_type, as_dict=1):
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 + jea.credit_in_account_currency"
amount_field = ("jea.debit_in_account_currency"
if party_type == 'Supplier' else "jea.credit_in_account_currency")
else:
amount_field = "jea.debit + jea.credit"
@@ -409,9 +436,9 @@ def get_pdc_details(party_type):
on
(jea.parent = je.name)
where
je.docstatus < 2 and je.cheque_date >= je.posting_date
je.docstatus < 2 and je.cheque_date >= %s
and jea.party_type = %s
group by jea.party, jea.reference_name""".format(amount_field), party_type, as_dict=1):
group by jea.party, jea.reference_name""".format(amount_field), (report_date, party_type), as_dict=1):
if (pdc.invoice_no, pdc.party) in pdc_details:
pdc_details[(pdc.invoice_no, pdc.party)]["pdc_amount"] += pdc.pdc_amount
else:

View File

@@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import flt
from erpnext.accounts.report.accounts_receivable.accounts_receivable import ReceivablePayableReport
class AccountsReceivableSummary(ReceivablePayableReport):
@@ -88,7 +89,8 @@ class AccountsReceivableSummary(ReceivablePayableReport):
})
)
for k in party_total[d.party].keys():
party_total[d.party][k] += d.get(k, 0)
if k != "currency":
party_total[d.party][k] += flt(d.get(k, 0))
party_total[d.party].currency = d.currency

View File

@@ -28,5 +28,10 @@ frappe.query_reports["Bank Reconciliation Statement"] = {
"default": frappe.datetime.get_today(),
"reqd": 1
},
{
"fieldname":"include_pos_transactions",
"label": __("Include POS Transactions"),
"fieldtype": "Check"
},
]
}
}

View File

@@ -138,7 +138,23 @@ def get_entries(filters):
and ifnull(clearance_date, '4000-01-01') > %(report_date)s
""", filters, as_dict=1)
return sorted(list(payment_entries)+list(journal_entries),
pos_entries = []
if filters.include_pos_transactions:
pos_entries = frappe.db.sql("""
select
"Sales Invoice Payment" as payment_document, sip.name as payment_entry, sip.amount as debit,
si.posting_date, si.debit_to as against_account, sip.clearance_date,
account.account_currency, 0 as credit
from `tabSales Invoice Payment` sip, `tabSales Invoice` si, `tabAccount` account
where
sip.account=%(account)s and si.docstatus=1 and sip.parent = si.name
and account.name = sip.account and si.posting_date <= %(report_date)s and
ifnull(sip.clearance_date, '4000-01-01') > %(report_date)s
order by
si.posting_date ASC, si.name DESC
""", filters, as_dict=1)
return sorted(list(payment_entries)+list(journal_entries+list(pos_entries)),
key=lambda k: k['posting_date'] or getdate(nowdate()))
def get_amounts_not_reflected_in_system(filters):

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

@@ -8,6 +8,13 @@
{%= filters.account %}
{% } %}
</h4>
<h6 class="text-center">
{% if (filters.tax_id) { %}
{%= __("Tax Id: ")%} {%= filters.tax_id %}
{% } %}
</h6>
<h5 class="text-center">
{%= dateutil.str_to_user(filters.from_date) %}
{%= __("to") %}

View File

@@ -61,7 +61,10 @@ frappe.query_reports["General Ledger"] = {
"label": __("Party Type"),
"fieldtype": "Link",
"options": "Party Type",
"default": ""
"default": "",
on_change: function() {
frappe.query_report_filters_by_name.party.set_value("");
}
},
{
"fieldname":"party",
@@ -82,11 +85,16 @@ frappe.query_reports["General Ledger"] = {
frappe.query_report_filters_by_name.party_name.set_value("");
return;
}
var fieldname = frappe.scrub(party_type) + "_name";
var fieldname = erpnext.utils.get_party_name(party_type) || "name";
frappe.db.get_value(party_type, party, fieldname, function(value) {
frappe.query_report_filters_by_name.party_name.set_value(value[fieldname]);
});
if (party_type === "Customer" || party_type === "Supplier") {
frappe.db.get_value(party_type, party, "tax_id", function(value) {
frappe.query_report_filters_by_name.tax_id.set_value(value["tax_id"]);
});
}
}
},
{
@@ -95,6 +103,12 @@ frappe.query_reports["General Ledger"] = {
"fieldtype": "Data",
"hidden": 1
},
{
"fieldname":"tax_id",
"label": __("Tax Id"),
"fieldtype": "Data",
"hidden": 1
},
{
"fieldname":"group_by_voucher",
"label": __("Group by Voucher"),

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 == "Employee" 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

@@ -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

View File

@@ -43,7 +43,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
row += [
supplier_details.get(inv.supplier), # supplier_type
inv.credit_to, inv.mode_of_payment, ", ".join(project),
inv.tax_id, inv.credit_to, inv.mode_of_payment, ", ".join(project),
inv.bill_no, inv.bill_date, inv.remarks,
", ".join(purchase_order), ", ".join(purchase_receipt), company_currency
]
@@ -83,7 +83,7 @@ def get_columns(invoice_list, additional_table_columns):
columns += additional_table_columns
columns += [
_("Supplier Type") + ":Link/Supplier Type:120", _("Payable Account") + ":Link/Account:120",
_("Supplier Type") + ":Link/Supplier Type:120", _("Tax Id") + "::80", _("Payable Account") + ":Link/Account:120",
_("Mode of Payment") + ":Link/Mode of Payment:80", _("Project") + ":Link/Project:80",
_("Bill No") + "::120", _("Bill Date") + ":Date:80", _("Remarks") + "::150",
_("Purchase Order") + ":Link/Purchase Order:100",
@@ -143,7 +143,7 @@ def get_invoices(filters, additional_query_columns):
conditions = get_conditions(filters)
return frappe.db.sql("""
select
name, posting_date, credit_to, supplier, supplier_name, bill_no, bill_date,
name, posting_date, credit_to, supplier, supplier_name, tax_id, bill_no, bill_date,
remarks, base_net_total, base_grand_total, outstanding_amount,
mode_of_payment {0}
from `tabPurchase Invoice`

View File

@@ -25,8 +25,6 @@ def _execute(filters, additional_table_columns=None, additional_query_columns=No
#Cost Center & Warehouse Map
invoice_cc_wh_map = get_invoice_cc_wh_map(invoice_list)
invoice_so_dn_map = get_invoice_so_dn_map(invoice_list)
customers = list(set([inv.customer for inv in invoice_list]))
customer_map = get_customer_details(customers)
company_currency = frappe.db.get_value("Company", filters.get("company"), "default_currency")
mode_of_payments = get_mode_of_payments([inv.name for inv in invoice_list])
@@ -38,7 +36,6 @@ def _execute(filters, additional_table_columns=None, additional_query_columns=No
cost_center = list(set(invoice_cc_wh_map.get(inv.name, {}).get("cost_center", [])))
warehouse = list(set(invoice_cc_wh_map.get(inv.name, {}).get("warehouse", [])))
customer_details = customer_map.get(inv.customer, {})
row = [
inv.name, inv.posting_date, inv.customer, inv.customer_name
]
@@ -48,8 +45,9 @@ def _execute(filters, additional_table_columns=None, additional_query_columns=No
row.append(inv.get(col))
row +=[
customer_details.get("customer_group"),
customer_details.get("territory"),
inv.get("customer_group"),
inv.get("territory"),
inv.get("tax_id"),
inv.debit_to, ", ".join(mode_of_payments.get(inv.name, [])),
inv.project, inv.owner, inv.remarks,
", ".join(sales_order), ", ".join(delivery_note),", ".join(cost_center),
@@ -92,7 +90,7 @@ def get_columns(invoice_list, additional_table_columns):
columns +=[
_("Customer Group") + ":Link/Customer Group:120", _("Territory") + ":Link/Territory:80",
_("Receivable Account") + ":Link/Account:120", _("Mode of Payment") + "::120",
_("Tax Id") + "::80", _("Receivable Account") + ":Link/Account:120", _("Mode of Payment") + "::120",
_("Project") +":Link/Project:80", _("Owner") + "::150", _("Remarks") + "::150",
_("Sales Order") + ":Link/Sales Order:100", _("Delivery Note") + ":Link/Delivery Note:100",
_("Cost Center") + ":Link/Cost Center:100", _("Warehouse") + ":Link/Warehouse:100",
@@ -162,7 +160,9 @@ def get_invoices(filters, additional_query_columns):
additional_query_columns = ', ' + ', '.join(additional_query_columns)
conditions = get_conditions(filters)
return frappe.db.sql("""select name, posting_date, debit_to, project, customer, customer_name, owner, remarks,
return frappe.db.sql("""
select name, posting_date, debit_to, project, customer,
customer_name, owner, remarks, territory, tax_id, customer_group,
base_net_total, base_grand_total, base_rounded_total, outstanding_amount {0}
from `tabSales Invoice`
where docstatus = 1 %s order by posting_date desc, name desc""".format(additional_query_columns or '') %
@@ -241,15 +241,6 @@ def get_invoice_cc_wh_map(invoice_list):
return invoice_cc_wh_map
def get_customer_details(customers):
customer_map = {}
for cust in frappe.db.sql("""select name, territory, customer_group from `tabCustomer`
where name in (%s)""" % ", ".join(["%s"]*len(customers)), tuple(customers), as_dict=1):
customer_map.setdefault(cust.name, cust)
return customer_map
def get_mode_of_payments(invoice_list):
mode_of_payments = {}
if invoice_list:

View File

@@ -5,6 +5,7 @@
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
from frappe import _
class Crop(Document):
def validate(self):
@@ -12,7 +13,7 @@ class Crop(Document):
for task in self.agriculture_task:
# validate start_day is not > end_day
if task.start_day > task.end_day:
frappe.throw("Start day is greater than end day in task '{0}'".format(task.subject))
frappe.throw(_("Start day is greater than end day in task '{0}'").format(task.task_name))
# to calculate the period of the Crop Cycle
if task.end_day > max_period: max_period = task.end_day
if max_period > self.period: self.period = max_period

View File

@@ -5,6 +5,7 @@
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
from frappe import _
class Disease(Document):
def validate(self):
@@ -12,7 +13,7 @@ class Disease(Document):
for task in self.treatment_task:
# validate start_day is not > end_day
if task.start_day > task.end_day:
frappe.throw("Start day is greater than end day in task '{0}'".format(task.task_name))
frappe.throw(_("Start day is greater than end day in task '{0}'").format(task.task_name))
# to calculate the period of the Crop Cycle
if task.end_day > max_period: max_period = task.end_day
self.treatment_period = max_period

View File

@@ -6,6 +6,7 @@ from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
from frappe.utils import flt, cint
from frappe import _
class SoilTexture(Document):
soil_edit_order = [2, 1, 0]
@@ -20,9 +21,9 @@ class SoilTexture(Document):
self.update_soil_edit('sand_composition')
for soil_type in self.soil_types:
if self.get(soil_type) > 100 or self.get(soil_type) < 0:
frappe.throw("{0} should be a value between 0 and 100".format(soil_type))
frappe.throw(_("{0} should be a value between 0 and 100").format(soil_type))
if sum(self.get(soil_type) for soil_type in self.soil_types) != 100:
frappe.throw('Soil compositions do not add up to 100')
frappe.throw(_('Soil compositions do not add up to 100'))
def update_soil_edit(self, soil_type):
self.soil_edit_order[self.soil_types.index(soil_type)] = max(self.soil_edit_order)+1

View File

@@ -5,6 +5,7 @@
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
from frappe import _
class WaterAnalysis(Document):
def load_contents(self):
@@ -18,6 +19,6 @@ class WaterAnalysis(Document):
def validate(self):
if self.collection_datetime > self.laboratory_testing_datetime:
frappe.throw('Lab testing datetime cannot be before collection datetime')
frappe.throw(_('Lab testing datetime cannot be before collection datetime'))
if self.laboratory_testing_datetime > self.result_datetime:
frappe.throw('Lab result datetime cannot be before testing datetime')
frappe.throw(_('Lab result datetime cannot be before testing datetime'))

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

@@ -15,6 +15,15 @@ frappe.ui.form.on("Purchase Order", {
frm.set_indicator_formatter('item_code',
function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" })
frm.set_query("reserve_warehouse", "supplied_items", function() {
return {
filters: {
"company": frm.doc.company,
"is_group": 0
}
}
});
},
onload: function(frm) {
@@ -134,23 +143,124 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
var items = $.map(cur_frm.doc.items, function(d) { return d.bom ? d.item_code : false; });
var me = this;
if(items.length===1) {
me._make_stock_entry(items[0]);
return;
if(items.length >= 1){
me.raw_material_data = [];
me.show_dialog = 1;
let title = "";
let fields = [
{fieldtype:'Section Break', label: __('Raw Materials')},
{fieldname: 'sub_con_rm_items', fieldtype: 'Table',
fields: [
{
fieldtype:'Data',
fieldname:'item_code',
label: __('Item'),
read_only:1,
in_list_view:1
},
{
fieldtype:'Data',
fieldname:'rm_item_code',
label: __('Raw Material'),
read_only:1,
in_list_view:1
},
{
fieldtype:'Float',
read_only:1,
fieldname:'qty',
label: __('Quantity'),
read_only:1,
in_list_view:1
},
{
fieldtype:'Data',
read_only:1,
fieldname:'warehouse',
label: __('Reserve Warehouse'),
in_list_view:1
},
{
fieldtype:'Float',
read_only:1,
fieldname:'rate',
label: __('Rate'),
hidden:1
},
{
fieldtype:'Float',
read_only:1,
fieldname:'amount',
label: __('Amount'),
hidden:1
},
{
fieldtype:'Link',
read_only:1,
fieldname:'uom',
label: __('UOM'),
hidden:1
}
],
data: me.raw_material_data,
get_data: function() {
return me.raw_material_data;
}
}
]
me.dialog = new frappe.ui.Dialog({
title: title, fields: fields
});
if (me.frm.doc['supplied_items']) {
me.frm.doc['supplied_items'].forEach((item, index) => {
if (item.rm_item_code && item.main_item_code) {
me.raw_material_data.push ({
'name':item.name,
'item_code': item.main_item_code,
'rm_item_code': item.rm_item_code,
'item_name': item.rm_item_code,
'qty': item.required_qty,
'warehouse':item.reserve_warehouse,
'rate':item.rate,
'amount':item.amount,
'stock_uom':item.stock_uom
});
me.dialog.fields_dict.sub_con_rm_items.grid.refresh();
}
})
}
frappe.prompt({fieldname:"item", options: items, fieldtype:"Select",
label: __("Select Item for Transfer"), reqd: 1}, function(data) {
me._make_stock_entry(data.item);
}, __("Select Item"), __("Make"));
me.dialog.show()
this.dialog.set_primary_action(__('Transfer'), function() {
me.values = me.dialog.get_values();
if(me.values) {
me.values.sub_con_rm_items.map((row,i) => {
if (!row.item_code || !row.rm_item_code || !row.warehouse || !row.qty || row.qty === 0) {
frappe.throw(__("Item Code, warehouse, quantity are required on row" + (i+1)));
}
})
me._make_rm_stock_entry(me.dialog.fields_dict.sub_con_rm_items.grid.get_selected_children())
me.dialog.hide()
}
});
}
me.dialog.get_close_btn().on('click', () => {
me.dialog.hide();
});
},
_make_stock_entry: function(item) {
_make_rm_stock_entry: function(rm_items) {
frappe.call({
method:"erpnext.buying.doctype.purchase_order.purchase_order.make_stock_entry",
method:"erpnext.buying.doctype.purchase_order.purchase_order.make_rm_stock_entry",
args: {
purchase_order: cur_frm.doc.name,
item_code: item
},
rm_items: rm_items
}
,
callback: function(r) {
var doclist = frappe.model.sync(r.message);
frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
@@ -284,7 +394,8 @@ cur_frm.fields_dict['items'].grid.get_field('bom').get_query = function(doc, cdt
filters: [
['BOM', 'item', '=', d.item_code],
['BOM', 'is_active', '=', '1'],
['BOM', 'docstatus', '=', '1']
['BOM', 'docstatus', '=', '1'],
['BOM', 'company', '=', doc.company]
]
}
}

View File

@@ -1207,7 +1207,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_bulk_edit": 1,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -3133,6 +3133,38 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.is_subcontracted",
"fieldname": "supplied_items_section",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Supplied Items",
"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": "",
"fieldname": "supplied_items",
"fieldtype": "Table",
"hidden": 0,
@@ -3323,7 +3355,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-02-17 11:00:05.037716",
"modified": "2018-07-06 11:00:05.037716",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order",

View File

@@ -12,7 +12,7 @@ from erpnext.stock.doctype.item.item import get_last_purchase_details
from erpnext.stock.stock_balance import update_bin_qty, get_ordered_qty
from frappe.desk.notifications import clear_doctype_notifications
from erpnext.buying.utils import validate_for_items, check_for_closed_status
from erpnext.stock.utils import get_bin
form_grid_templates = {
"items": "templates/form_grid/item_grid.html"
@@ -80,8 +80,10 @@ class PurchaseOrder(BuyingController):
def validate_supplier(self):
prevent_po = frappe.db.get_value("Supplier", self.supplier, 'prevent_pos')
if prevent_po:
standing = frappe.db.get_value("Supplier Scorecard",self.supplier, 'status')
frappe.throw(_("Purchase Orders are not allowed for {0} due to a scorecard standing of {1}.").format(self.supplier, standing))
standing = frappe.db.get_value("Supplier Scorecard", self.supplier, 'status')
if standing:
frappe.throw(_("Purchase Orders are not allowed for {0} due to a scorecard standing of {1}.")
.format(self.supplier, standing))
warn_po = frappe.db.get_value("Supplier", self.supplier, 'warn_pos')
if warn_po:
@@ -192,6 +194,9 @@ class PurchaseOrder(BuyingController):
self.set_status(update=True, status=status)
self.update_requested_qty()
self.update_ordered_qty()
if self.is_subcontracted == "Yes":
self.update_reserved_qty_for_subcontract()
self.notify_update()
clear_doctype_notifications(self)
@@ -204,6 +209,8 @@ class PurchaseOrder(BuyingController):
self.update_prevdoc_status()
self.update_requested_qty()
self.update_ordered_qty()
if self.is_subcontracted == "Yes":
self.update_reserved_qty_for_subcontract()
frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
self.company, self.base_grand_total)
@@ -217,6 +224,9 @@ class PurchaseOrder(BuyingController):
if self.has_drop_ship_item():
self.update_delivered_qty_in_sales_order()
if self.is_subcontracted == "Yes":
self.update_reserved_qty_for_subcontract()
self.check_for_closed_status()
frappe.db.set(self,'status','Cancelled')
@@ -268,6 +278,12 @@ class PurchaseOrder(BuyingController):
if item.delivered_by_supplier == 1:
item.received_qty = item.qty
def update_reserved_qty_for_subcontract(self):
for d in self.supplied_items:
if d.rm_item_code:
stock_bin = get_bin(d.rm_item_code, d.reserve_warehouse)
stock_bin.update_reserved_qty_for_sub_contracting()
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
@@ -388,23 +404,52 @@ def make_purchase_invoice(source_name, target_doc=None):
return doc
@frappe.whitelist()
def make_stock_entry(purchase_order, item_code):
purchase_order = frappe.get_doc("Purchase Order", purchase_order)
def make_rm_stock_entry(purchase_order, rm_items):
if isinstance(rm_items, basestring):
rm_items_list = json.loads(rm_items)
else:
frappe.throw(_("No Items available for transfer"))
stock_entry = frappe.new_doc("Stock Entry")
stock_entry.purpose = "Subcontract"
stock_entry.purchase_order = purchase_order.name
stock_entry.supplier = purchase_order.supplier
stock_entry.supplier_name = purchase_order.supplier_name
stock_entry.supplier_address = purchase_order.supplier_address
stock_entry.address_display = purchase_order.address_display
stock_entry.company = purchase_order.company
stock_entry.from_bom = 1
po_item = [d for d in purchase_order.items if d.item_code == item_code][0]
stock_entry.fg_completed_qty = po_item.qty
stock_entry.bom_no = po_item.bom
stock_entry.get_items()
return stock_entry.as_dict()
if rm_items_list:
fg_items = list(set(d["item_code"] for d in rm_items_list))
else:
frappe.throw(_("No Items selected for transfer"))
if purchase_order:
purchase_order = frappe.get_doc("Purchase Order", purchase_order)
if fg_items:
items = tuple(set(d["rm_item_code"] for d in rm_items_list))
item_wh = frappe._dict(frappe.db.sql("""
select item_code, description
from `tabItem` where name in ({0})
""".format(", ".join(["%s"] * len(items))), items))
stock_entry = frappe.new_doc("Stock Entry")
stock_entry.purpose = "Subcontract"
stock_entry.purchase_order = purchase_order.name
stock_entry.supplier = purchase_order.supplier
stock_entry.supplier_name = purchase_order.supplier_name
stock_entry.supplier_address = purchase_order.supplier_address
stock_entry.address_display = purchase_order.address_display
stock_entry.company = purchase_order.company
for item_code in fg_items:
for rm_item_data in rm_items_list:
if rm_item_data["item_code"] == item_code:
items_dict = {
rm_item_data["rm_item_code"]: {
"item_name":rm_item_data["item_name"],
"description":item_wh.get(rm_item_data["rm_item_code"]),
'qty':rm_item_data["qty"],
'from_warehouse':rm_item_data["warehouse"],
'stock_uom':rm_item_data["stock_uom"]
}
}
stock_entry.add_to_stock_entry_detail(items_dict)
return stock_entry.as_dict()
else:
frappe.throw(_("No Items selected for transfer"))
return purchase_order.name
@frappe.whitelist()
def update_status(status, name):

View File

@@ -6,8 +6,9 @@ import unittest
import frappe
import frappe.defaults
from frappe.utils import flt, add_days, nowdate
from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt, make_purchase_invoice
from erpnext.buying.doctype.purchase_order.purchase_order import (make_purchase_receipt, make_purchase_invoice, make_rm_stock_entry as make_subcontract_transfer_entry)
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
import json
class TestPurchaseOrder(unittest.TestCase):
def test_make_purchase_receipt(self):
@@ -182,24 +183,129 @@ class TestPurchaseOrder(unittest.TestCase):
pi.insert()
self.assertTrue(pi.get('payment_schedule'))
def test_reserved_qty_subcontract_po(self):
# Make stock available for raw materials
make_stock_entry(target="_Test Warehouse - _TC", qty=10, basic_rate=100)
make_stock_entry(target="_Test Warehouse - _TC", item_code="_Test Item Home Desktop 100",
qty=20, basic_rate=100)
bin1 = frappe.db.get_value("Bin",
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
fieldname=["reserved_qty_for_sub_contract", "projected_qty"], as_dict=1)
# Submit PO
po = create_purchase_order(item_code="_Test FG Item", is_subcontracted="Yes")
bin2 = frappe.db.get_value("Bin",
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
fieldname=["reserved_qty_for_sub_contract", "projected_qty"], as_dict=1)
self.assertEquals(bin2.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract + 10)
self.assertEquals(bin2.projected_qty, bin1.projected_qty - 10)
# Create stock transfer
rm_item = [{"item_code":"_Test FG Item","rm_item_code":"_Test Item","item_name":"_Test Item",
"qty":6,"warehouse":"_Test Warehouse - _TC","rate":100,"amount":600,"stock_uom":"Nos"}]
rm_item_string = json.dumps(rm_item)
se = frappe.get_doc(make_subcontract_transfer_entry(po.name, rm_item_string))
se.to_warehouse = "_Test Warehouse 1 - _TC"
se.save()
se.submit()
bin3 = frappe.db.get_value("Bin",
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
fieldname="reserved_qty_for_sub_contract", as_dict=1)
self.assertEquals(bin3.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
# close PO
po.update_status("Closed")
bin4 = frappe.db.get_value("Bin",
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
fieldname="reserved_qty_for_sub_contract", as_dict=1)
self.assertEquals(bin4.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract)
# Re-open PO
po.update_status("Submitted")
bin5 = frappe.db.get_value("Bin",
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
fieldname="reserved_qty_for_sub_contract", as_dict=1)
self.assertEquals(bin5.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
# make Purchase Receipt against PO
pr = make_purchase_receipt(po.name)
pr.supplier_warehouse = "_Test Warehouse 1 - _TC"
pr.save()
pr.submit()
bin6 = frappe.db.get_value("Bin",
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
fieldname="reserved_qty_for_sub_contract", as_dict=1)
self.assertEquals(bin6.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract)
# Cancel PR
pr.cancel()
bin7 = frappe.db.get_value("Bin",
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
fieldname="reserved_qty_for_sub_contract", as_dict=1)
self.assertEquals(bin7.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
# Make Purchase Invoice
pi = make_purchase_invoice(po.name)
pi.update_stock = 1
pi.supplier_warehouse = "_Test Warehouse 1 - _TC"
pi.insert()
pi.submit()
bin8 = frappe.db.get_value("Bin",
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
fieldname="reserved_qty_for_sub_contract", as_dict=1)
self.assertEquals(bin8.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract)
# Cancel PR
pi.cancel()
bin9 = frappe.db.get_value("Bin",
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
fieldname="reserved_qty_for_sub_contract", as_dict=1)
self.assertEquals(bin9.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
# Cancel Stock Entry
se.cancel()
bin10 = frappe.db.get_value("Bin",
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
fieldname="reserved_qty_for_sub_contract", as_dict=1)
self.assertEquals(bin10.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract + 10)
# Cancel PO
po.reload()
po.cancel()
bin11 = frappe.db.get_value("Bin",
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
fieldname="reserved_qty_for_sub_contract", as_dict=1)
self.assertEquals(bin11.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract)
def get_same_items():
return [
{
"item_code": "_Test FG Item",
"warehouse": "_Test Warehouse - _TC",
"qty": 1,
"rate": 500,
"schedule_date": add_days(nowdate(), 1)
},
{
"item_code": "_Test FG Item",
"warehouse": "_Test Warehouse - _TC",
"qty": 4,
"rate": 500,
"schedule_date": add_days(nowdate(), 1)
}
]
{
"item_code": "_Test FG Item",
"warehouse": "_Test Warehouse - _TC",
"qty": 1,
"rate": 500,
"schedule_date": add_days(nowdate(), 1)
},
{
"item_code": "_Test FG Item",
"warehouse": "_Test Warehouse - _TC",
"qty": 4,
"rate": 500,
"schedule_date": add_days(nowdate(), 1)
}
]
def create_purchase_order(**args):
po = frappe.new_doc("Purchase Order")
@@ -224,6 +330,10 @@ def create_purchase_order(**args):
if not args.do_not_save:
po.insert()
if not args.do_not_submit:
if po.is_subcontracted == "Yes":
supp_items = po.get("supplied_items")
for d in supp_items:
d.reserve_warehouse = args.warehouse or "_Test Warehouse - _TC"
po.submit()
return po

View File

@@ -1,5 +1,6 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
@@ -10,68 +11,86 @@
"editable_grid": 1,
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 2,
"fieldname": "main_item_code",
"fieldtype": "Data",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Item Code",
"length": 0,
"no_copy": 0,
"oldfieldname": "main_item_code",
"oldfieldtype": "Data",
"options": "Item",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 2,
"fieldname": "rm_item_code",
"fieldtype": "Data",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Raw Material Item Code",
"length": 0,
"no_copy": 0,
"oldfieldname": "rm_item_code",
"oldfieldtype": "Data",
"options": "Item",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 2,
"fieldname": "required_qty",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Supplied Qty",
"length": 0,
"no_copy": 0,
@@ -81,23 +100,29 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 2,
"fieldname": "rate",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Rate",
"length": 0,
"no_copy": 0,
@@ -108,23 +133,29 @@
"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": "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": "Amount",
"length": 0,
"no_copy": 0,
@@ -135,23 +166,59 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_6",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "bom_detail_no",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "BOM Detail No",
"length": 0,
"no_copy": 0,
@@ -161,23 +228,29 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "reference_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Reference Name",
"length": 0,
"no_copy": 0,
@@ -187,23 +260,29 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "conversion_factor",
"fieldtype": "Float",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Conversion Factor",
"length": 0,
"no_copy": 0,
@@ -213,23 +292,29 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "stock_uom",
"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": "Stock Uom",
"length": 0,
"no_copy": 0,
@@ -240,24 +325,58 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 2,
"fieldname": "reserve_warehouse",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Reserve Warehouse",
"length": 0,
"no_copy": 0,
"options": "Warehouse",
"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": 1,
"idx": 1,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2016-07-11 03:28:05.533063",
"modified": "2018-03-13 12:37:57.150914",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order Item Supplied",
@@ -266,5 +385,7 @@
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"track_changes": 0,
"track_seen": 0
}

View File

@@ -1,5 +1,6 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
@@ -11,12 +12,13 @@
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "main_item_code",
"fieldtype": "Data",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -29,6 +31,7 @@
"no_copy": 0,
"oldfieldname": "main_item_code",
"oldfieldtype": "Data",
"options": "Item",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@@ -38,15 +41,17 @@
"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": "rm_item_code",
"fieldtype": "Data",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -59,6 +64,7 @@
"no_copy": 0,
"oldfieldname": "rm_item_code",
"oldfieldtype": "Data",
"options": "Item",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@@ -68,9 +74,11 @@
"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,
@@ -99,10 +107,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0,
"width": "300px"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -129,9 +139,11 @@
"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,
@@ -157,9 +169,11 @@
"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,
@@ -184,9 +198,11 @@
"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,
@@ -214,9 +230,11 @@
"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,
@@ -244,9 +262,11 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -275,9 +295,11 @@
"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,
@@ -306,9 +328,11 @@
"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,
@@ -337,9 +361,11 @@
"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,
@@ -367,9 +393,11 @@
"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,
@@ -397,9 +425,11 @@
"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,
@@ -427,9 +457,11 @@
"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,
@@ -457,20 +489,21 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2017-02-17 16:43:21.668443",
"modified": "2018-03-13 12:38:40.807453",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Receipt Item Supplied",

View File

@@ -781,7 +781,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_bulk_edit": 1,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -2177,6 +2177,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_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,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "letter_head",
"fieldtype": "Link",
"hidden": 0,
@@ -2490,7 +2549,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2017-11-29 14:07:56.698355",
"modified": "2018-07-06 02:45:48.616334",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Quotation",

View File

@@ -126,6 +126,11 @@ def get_data():
"link": "Tree/Sales Person",
"description": _("Manage Sales Person Tree."),
},
{
"type": "doctype",
"name": "Lead Source",
"description": _("Track Leads by Lead Source.")
},
]
},
{

View File

@@ -200,7 +200,7 @@ def get_data():
"color": "#fd784f",
"icon": "octicon octicon-calendar",
"label": _("Course Schedule"),
"link": "Calendar/Course Schedule",
"link": "List/Course Schedule/Calendar",
"_doctype": "Course Schedule",
"type": "list",
"hidden": 1

View File

@@ -135,6 +135,10 @@ def get_data():
"name": "Assessment Plan Status",
"doctype": "Assessment Plan"
},
{
"type": "doctype",
"name": "Student Report Generation Tool"
}
]
},
{

View File

@@ -173,6 +173,11 @@ def get_data():
"name": "Industry Type",
"description": _("Track Leads by Industry Type.")
},
{
"type": "doctype",
"name": "Lead Source",
"description": _("Track Leads by Lead Source.")
},
]
},
{

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,6 +131,8 @@ 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:
@@ -232,7 +235,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 +243,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 +666,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)
@@ -666,7 +675,9 @@ class AccountsController(TransactionBase):
self.remove(item)
def set_payment_schedule(self):
if self.doctype == 'Sales Invoice' and self.is_pos: return
if self.doctype == 'Sales Invoice' and self.is_pos:
self.payment_terms_template = ''
return
posting_date = self.get("bill_date") or self.get("posting_date") or self.get("transaction_date")
date = self.get("due_date")

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()
@@ -163,6 +164,11 @@ class BuyingController(StockController):
if item in self.sub_contracted_items and not item.bom:
frappe.throw(_("Please select BOM in BOM field for Item {0}").format(item.item_code))
if self.doctype == "Purchase Order":
for supplied_item in self.get("supplied_items"):
if not supplied_item.reserve_warehouse:
frappe.throw(_("Reserved Warehouse is mandatory for Item {0} in Raw Materials supplied").format(frappe.bold(supplied_item.rm_item_code)))
else:
for item in self.get("items"):
if item.bom:
@@ -192,8 +198,16 @@ class BuyingController(StockController):
def update_raw_materials_supplied(self, item, raw_material_table):
bom_items = self.get_items_from_bom(item.item_code, item.bom)
raw_materials_cost = 0
items = list(set([d.item_code for d in bom_items]))
item_wh = frappe._dict(frappe.db.sql("""select item_code, default_warehouse
from `tabItem` where name in ({0})""".format(", ".join(["%s"] * len(items))), items))
for bom_item in bom_items:
if self.doctype == "Purchase Order":
reserve_warehouse = bom_item.source_warehouse or item_wh.get(bom_item.item_code)
if frappe.db.get_value("Warehouse", reserve_warehouse, "company") != self.company:
reserve_warehouse = None
# check if exists
exists = 0
for d in self.get(raw_material_table):
@@ -213,6 +227,8 @@ class BuyingController(StockController):
rm.rm_item_code = bom_item.item_code
rm.stock_uom = bom_item.stock_uom
rm.required_qty = required_qty
if self.doctype == "Purchase Order" and not rm.reserve_warehouse:
rm.reserve_warehouse = reserve_warehouse
rm.conversion_factor = item.conversion_factor
@@ -264,7 +280,7 @@ class BuyingController(StockController):
def get_items_from_bom(self, item_code, bom):
bom_items = frappe.db.sql("""select t2.item_code,
t2.stock_qty / ifnull(t1.quantity, 1) as qty_consumed_per_unit,
t2.rate, t2.stock_uom, t2.name, t2.description
t2.rate, t2.stock_uom, t2.name, t2.description, t2.source_warehouse
from `tabBOM` t1, `tabBOM Item` t2, tabItem t3
where t2.parent = t1.name and t1.item = %s
and t1.docstatus = 1 and t1.is_active = 1 and t1.name = %s
@@ -339,7 +355,7 @@ class BuyingController(StockController):
frappe.get_meta(item_row.doctype).get_label(fieldname), item_row['item_code'])))
def update_stock_ledger(self, allow_negative_stock=False, via_landed_cost_voucher=False):
self.update_ordered_qty()
self.update_ordered_and_reserved_qty()
sl_entries = []
stock_items = self.get_stock_items()
@@ -381,7 +397,7 @@ class BuyingController(StockController):
self.make_sl_entries(sl_entries, allow_negative_stock=allow_negative_stock,
via_landed_cost_voucher=via_landed_cost_voucher)
def update_ordered_qty(self):
def update_ordered_and_reserved_qty(self):
po_map = {}
for d in self.get("items"):
if self.doctype=="Purchase Receipt" \
@@ -400,6 +416,8 @@ class BuyingController(StockController):
frappe.InvalidStatusError)
po_obj.update_ordered_qty(po_item_rows)
if self.is_subcontracted:
po_obj.update_reserved_qty_for_subcontract()
def make_sl_entries_for_supplier_warehouse(self, sl_entries):
if hasattr(self, 'supplied_items'):
@@ -439,3 +457,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

@@ -92,7 +92,10 @@ def validate_is_incremental(numeric_attribute, attribute, value, item):
InvalidItemAttributeValueError, title=_('Invalid Attribute'))
def validate_item_attribute_value(attributes_list, attribute, attribute_value, item):
if attribute_value not in attributes_list:
allow_rename_attribute_value = frappe.db.get_single_value('Item Variant Settings', 'allow_rename_attribute_value')
if allow_rename_attribute_value:
pass
elif attribute_value not in attributes_list:
frappe.throw(_("Value {0} for Attribute {1} does not exist in the list of valid Item Attribute Values for Item {2}").format(
attribute_value, attribute, item), InvalidItemAttributeValueError, title=_('Invalid Attribute'))
@@ -173,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

@@ -152,9 +152,15 @@ def tax_account_query(doctype, txt, searchfield, start, page_len, filters):
def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=False):
conditions = []
return frappe.db.sql("""select tabItem.name, tabItem.item_group,
description_cond = ''
if frappe.db.count('Item', cache=True) < 50000:
# scan description only if items are less than 50000
description_cond = 'or tabItem.description LIKE %(txt)s'
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
@@ -166,7 +172,7 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals
or tabItem.item_group LIKE %(txt)s
or tabItem.item_name LIKE %(txt)s
or tabItem.barcode LIKE %(txt)s
or tabItem.description LIKE %(txt)s)
{description_cond})
{fcond} {mcond}
order by
if(locate(%(_txt)s, name), locate(%(_txt)s, name), 99999),
@@ -176,7 +182,8 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals
limit %(start)s, %(page_len)s """.format(
key=searchfield,
fcond=get_filters_cond(doctype, filters, conditions).replace('%', '%%'),
mcond=get_match_cond(doctype).replace('%', '%%')),
mcond=get_match_cond(doctype).replace('%', '%%'),
description_cond = description_cond),
{
"today": nowdate(),
"txt": "%%%s%%" % txt,

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)
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,
@@ -160,10 +165,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):
@@ -239,6 +244,7 @@ def make_return_doc(doctype, source_name, target_doc=None):
target_doc.received_qty = -1* source_doc.received_qty
target_doc.rejected_qty = -1* source_doc.rejected_qty
target_doc.qty = -1* source_doc.qty
target_doc.stock_qty = -1 * source_doc.stock_qty
target_doc.purchase_order = source_doc.purchase_order
target_doc.purchase_order_item = source_doc.purchase_order_item
target_doc.rejected_warehouse = source_doc.rejected_warehouse
@@ -246,6 +252,7 @@ def make_return_doc(doctype, source_name, target_doc=None):
target_doc.received_qty = -1* source_doc.received_qty
target_doc.rejected_qty = -1* source_doc.rejected_qty
target_doc.qty = -1* source_doc.qty
target_doc.stock_qty = -1 * source_doc.stock_qty
target_doc.purchase_order = source_doc.purchase_order
target_doc.purchase_receipt = source_doc.purchase_receipt
target_doc.rejected_warehouse = source_doc.rejected_warehouse

View File

@@ -35,9 +35,11 @@ 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()
self.set_po_nos()
check_active_sales_items(self)
def set_missing_values(self, for_validate=False):
@@ -326,9 +328,21 @@ class SellingController(StockController):
"actual_qty": -1*flt(d.qty),
"incoming_rate": return_rate
}))
self.make_sl_entries(sl_entries)
def set_po_nos(self):
if self.doctype in ("Delivery Note", "Sales Invoice") and hasattr(self, "items"):
ref_fieldname = "against_sales_order" if self.doctype == "Delivery Note" else "sales_order"
sales_orders = list(set([d.get(ref_fieldname) for d in self.items if d.get(ref_fieldname)]))
if sales_orders:
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

@@ -156,6 +156,9 @@ class StatusUpdater(Document):
# get unique transactions to update
for d in self.get_all_children():
if hasattr(d, 'qty') and d.qty < 0 and not self.get('is_return'):
frappe.throw(_("For an item {0}, quantity must be positive number").format(d.item_code))
if d.doctype == args['source_dt'] and d.get(args["join_field"]):
args['name'] = d.get(args['join_field'])
@@ -282,7 +285,7 @@ class StatusUpdater(Document):
ifnull((select
ifnull(sum(if(%(target_ref_field)s > %(target_field)s, abs(%(target_field)s), abs(%(target_ref_field)s))), 0)
/ sum(abs(%(target_ref_field)s)) * 100
from `tab%(target_dt)s` where parent="%(name)s"), 0), 2)
from `tab%(target_dt)s` where parent="%(name)s" having sum(abs(%(target_ref_field)s)) > 0), 0), 6)
%(update_modified)s
where name='%(name)s'""" % args)
@@ -290,7 +293,7 @@ class StatusUpdater(Document):
if args.get('status_field'):
frappe.db.sql("""update `tab%(target_parent_dt)s`
set %(status_field)s = if(%(target_parent_field)s<0.001,
'Not %(keyword)s', if(%(target_parent_field)s>=99.99,
'Not %(keyword)s', if(%(target_parent_field)s>=99.999999,
'Fully %(keyword)s', 'Partly %(keyword)s'))
where name='%(name)s'""" % args)

View File

@@ -252,7 +252,7 @@ class StockController(AccountsController):
"company": self.company,
"batch_no": cstr(d.get("batch_no")).strip(),
"serial_no": d.get("serial_no"),
"project": d.get("project"),
"project": d.get("project") or self.get('project'),
"is_cancelled": self.docstatus==2 and "Yes" or "No"
})

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

@@ -34,14 +34,14 @@ def work():
payroll_entry.salary_slip_based_on_timesheet = 0
payroll_entry.create_salary_slips()
payroll_entry.submit_salary_slips()
payroll_entry.make_accural_jv_entry()
payroll_entry.make_accrual_jv_entry()
# payroll_entry.make_journal_entry(reference_date=frappe.flags.current_date,
# reference_number=random_string(10))
payroll_entry.salary_slip_based_on_timesheet = 1
payroll_entry.create_salary_slips()
payroll_entry.submit_salary_slips()
payroll_entry.make_accural_jv_entry()
payroll_entry.make_accrual_jv_entry()
# payroll_entry.make_journal_entry(reference_date=frappe.flags.current_date,
# reference_number=random_string(10))

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

@@ -24,7 +24,7 @@ In the document, you can select multiple Purchase Receipts and fetch all items f
<img class="screenshot" alt="Landed Cost Vouher" src="/docs/assets/img/stock/landed-cost.png">
### What happend on submission?
### What happens on submission?
1. On submission of Landed Cost Voucher, the applicable landed cost charges are updated in Purchase Receipt Item table.

View File

@@ -2,7 +2,7 @@
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 0,
"allow_rename": 1,
"autoname": "GARD.####",
"beta": 0,
"creation": "2016-07-21 15:32:51.163292",
@@ -507,7 +507,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-12-06 18:17:38.090252",
"modified": "2018-03-07 12:51:06.941609",
"modified_by": "Administrator",
"module": "Education",
"name": "Guardian",

View File

@@ -16,6 +16,12 @@ frappe.ui.form.on("Program Enrollment Tool", {
});
},
get_students_from: function(frm) {
if (frm.doc.get_students_from == "Student Applicant") {
frm.dashboard.add_comment(__('Only the Student Applicant with the status "Approved" will be selected in the table below.'));
}
},
"get_students": function(frm) {
frm.set_value("students",[]);
frappe.call({

View File

@@ -26,7 +26,7 @@ class ProgramEnrollmentTool(Document):
elif self.get_students_from == "Program Enrollment":
condition2 = 'and student_batch_name=%(student_batch)s' if self.student_batch else " "
students = frappe.db.sql('''select student, student_name, student_batch_name from `tabProgram Enrollment`
where program=%(program)s and academic_year=%(academic_year)s {0} {1}'''
where program=%(program)s and academic_year=%(academic_year)s {0} {1} and docstatus != 2'''
.format(condition, condition2), self.as_dict(), as_dict=1)
student_list = [d.student for d in students]

View File

@@ -22,14 +22,16 @@ class Student(Document):
def update_student_name_in_linked_doctype(self):
linked_doctypes = get_linked_doctypes("Student")
for d in linked_doctypes:
if "student_name" in [f.fieldname for f in frappe.get_meta(d).fields]:
frappe.db.sql("""UPDATE `tab{0}` set student_name = %s where {1} = %s"""
.format(d, linked_doctypes[d]["fieldname"]),(self.title, self.name))
meta = frappe.get_meta(d)
if not meta.issingle:
if "student_name" in [f.fieldname for f in meta.fields]:
frappe.db.sql("""UPDATE `tab{0}` set student_name = %s where {1} = %s"""
.format(d, linked_doctypes[d]["fieldname"]),(self.title, self.name))
if "child_doctype" in linked_doctypes[d].keys() and "student_name" in \
[f.fieldname for f in frappe.get_meta(linked_doctypes[d]["child_doctype"]).fields]:
frappe.db.sql("""UPDATE `tab{0}` set student_name = %s where {1} = %s"""
.format(linked_doctypes[d]["child_doctype"], linked_doctypes[d]["fieldname"]),(self.title, self.name))
if "child_doctype" in linked_doctypes[d].keys() and "student_name" in \
[f.fieldname for f in frappe.get_meta(linked_doctypes[d]["child_doctype"]).fields]:
frappe.db.sql("""UPDATE `tab{0}` set student_name = %s where {1} = %s"""
.format(linked_doctypes[d]["child_doctype"], linked_doctypes[d]["fieldname"]),(self.title, self.name))
def check_unique(self):
"""Validates if the Student Applicant is Unique"""

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

@@ -0,0 +1,371 @@
<style>
@media screen {
.print-format-gutter {
background-color: #ddd;
padding: 15px 0px;
}
.print-format {
background-color: white;
box-shadow: 0px 0px 9px rgba(0,0,0,0.5);
max-width: 8.3in;
min-height: 11.69in;
padding: 0.75in;
margin: auto;
}
.print-format.landscape {
max-width: 11.69in;
padding: 0.2in;
}
.page-break {
padding: 30px 0px;
border-bottom: 1px dashed #888;
}
.page-break:first-child {
padding-top: 0px;
}
.page-break:last-child {
border-bottom: 0px;
}
/* mozilla hack for images in table */
body:last-child .print-format td img {
width: 100% !important;
}
@media(max-width: 767px) {
.print-format {
padding: 0.2in;
}
}
}
@media print {
.print-format p {
margin-left: 1px;
margin-right: 1px;
}
}
.data-field {
margin-top: 5px;
margin-bottom: 5px;
}
.data-field .value {
word-wrap: break-word;
}
.important .value {
font-size: 120%;
font-weight: bold;
}
.important label {
line-height: 1.8;
margin: 0px;
}
.table {
margin: 20px 0px;
}
.square-image {
width: 100%;
height: 0;
padding: 50% 0;
background-size: contain;
/*background-size: cover;*/
background-repeat: no-repeat !important;
background-position: center center;
border-radius: 4px;
}
.print-item-image {
object-fit: contain;
}
.pdf-variables,
.pdf-variable,
.visible-pdf {
display: none !important;
}
.print-format {
font-size: 9pt;
font-family: "Helvetica Neue", Helvetica, Arial, "Open Sans", sans-serif;
-webkit-print-color-adjust:exact;
}
.page-break {
page-break-after: always;
}
.print-heading {
border-bottom: 1px solid #aaa;
margin-bottom: 10px;
}
.print-heading h2 {
margin: 0px;
}
.print-heading h4 {
margin-top: 5px;
}
table.no-border, table.no-border td {
border: 0px;
}
.print-format label {
/* wkhtmltopdf breaks label into multiple lines when it is inline-block */
display: block;
}
.print-format img {
max-width: 100%;
}
.print-format table td > .primary:first-child {
font-weight: bold;
}
.print-format td, .print-format th {
vertical-align: top !important;
padding: 6px !important;
}
.print-format p {
margin: 3px 0px 3px;
}
table td div {
/* needed to avoid partial cutting of text between page break in wkhtmltopdf */
page-break-inside: avoid !important;
}
/* hack for webkit specific browser */
@media (-webkit-min-device-pixel-ratio:0) {
thead, tfoot { display: table-row-group; }
}
[document-status] {
margin-bottom: 5mm;
}
.signature-img {
background: #fff;
border-radius: 3px;
margin-top: 5px;
max-height: 150px;
}
.print-heading {
text-align: right;
text-transform: uppercase;
color: #666;
padding-bottom: 20px;
margin-bottom: 20px;
border-bottom: 1px solid #d1d8dd;
}
.print-heading h2 {
font-size: 24px;
}
.print-format th {
background-color: #eee !important;
border-bottom: 0px !important;
}
/* modern format: for-test */
.pbi_avoid {
page-break-inside: avoid !important;
}
.pb_before {
page-break-before: always !important;
}
</style>
<div class="page-break">
<div id="header-html" class="hidden-pdf">
{% if letterhead and add_letterhead %}
<div class="">{{ letterhead }}</div>
{% endif %}
<div class="print-heading">
<h2>{{ _("Student Report Card") }}<br>
<small>{{ doc.student_name }}</small>
</h2>
</div>
</div>
<div class="row section-break">
<div class="col-xs-6 column-break">
<div class="row data-field">
<div class="col-xs-5">
<label>{{ _("Student ID: ") }}</label>
</div>
<div class="col-xs-7">
{{ doc.students[0] }}
</div>
</div>
<div class="row data-field">
<div class="col-xs-5">
<label>{{ _("Student Name: ") }}</label>
</div>
<div class="col-xs-7">
{{ doc.student_name }}
</div>
</div>
<div class="row data-field">
<div class="col-xs-5">
<label>{{ _("Program: ") }}</label>
</div>
<div class="col-xs-7">
{{ doc.program }}
</div>
</div>
<div class="row data-field">
<div class="col-xs-5">
<label>{{ _("Batch: ") }}</label>
</div>
<div class="col-xs-7">
{{ doc.student_batch }}
</div>
</div>
</div>
<div class="col-xs-6 column-break">
<div class="row data-field">
<div class="col-xs-5">
<label>{{ _("Academic Year: ") }}</label>
</div>
<div class="col-xs-7">
{{ doc.academic_year }}
</div>
</div>
{% if doc.academic_term %}
<div class="row data-field">
<div class="col-xs-5">
<label>{{ _("Academic Term: ") }}</label>
</div>
<div class="col-xs-7">
{{ doc.academic_term }}
</div>
</div>
{% endif %}
<div class="row data-field">
<div class="col-xs-5">
<label>{{ _("Assessment Group: ") }}</label>
</div>
<div class="col-xs-7">
{{ doc.assessment_group }}
</div>
</div>
</div>
</div>
{% if doc.show_marks | int %}
{% set result_data = 'score' %}
{% else %}
{% set result_data = 'grade' %}
{% endif %}
{% for course in courses %}
<div class="row section-break pbi_avoid">
<div class="col-xs-12 column-break">
<div>
<table class="table table-bordered table-condensed">
<caption>
<div class="row">
<div class="col-xs-1">
<label>{{ _("Course: ") }}</label>
</div>
<div class="col-xs-11">
{{ course }} ({{ frappe.db.get_value("Course", course, "course_name") }})
</div>
</div>
</caption>
<thead>
<tr>
<th style="width: {{ 650//(assessment_groups|length + 1) }}px">{{ _("Assessment Criteria") }}</th>
{% for assessment_group in assessment_groups %}
<th> {{ assessment_group }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for criteria in course_criteria[course] %}
<tr>
<td>{{ criteria }}</td>
{% for assessment_group in assessment_groups %}
{% if (assessment_result.get(course) and assessment_result.get(course).get(assessment_group) and assessment_result.get(course).get(assessment_group).get(criteria)) %}
<td>
{{ assessment_result.get(course).get(assessment_group).get(criteria).get(result_data) }}
{% if result_data == 'score' %}
({{ assessment_result.get(course).get(assessment_group).get(criteria).get('maximum_score') }})
{% endif %}
</td>
{% else %}
<td></td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endfor %}
<br>
<div class="row section-break pbi_avoid">
<div class="col-xs-6 column-break">
<h4>{{ _("Student Attendance")}}</h4> <br>
<div>
Present {{ doc.attendance.get("Present") if doc.attendance.get("Present") != None else '0' }} days
out of {{ doc.attendance.get("Present") + doc.attendance.get("Absent") }}
</div>
</div>
<div class="col-xs-6 column-break">
<h4>{{ _("Parents Teacher Meeting Attendance")}}</h4> <br>
<div>
Present {{ doc.parents_attendance if doc.parents_attendance != None else '0' }}
out of {{ doc.parents_meeting if doc.parents_meeting != None else '0' }}
</div>
</div>
</div>
{% if doc.assessment_terms %}
<div class="row section-break pb_before">
<div class="col-xs-12">
<p> {{ doc.assessment_terms }} </p>
</div>
</div>
{% endif %}
</div>

View File

@@ -0,0 +1,66 @@
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.ui.form.on('Student Report Generation Tool', {
onload: function(frm) {
frm.set_query("academic_term",function(){
return{
"filters":{
"academic_year": frm.doc.academic_year
}
};
});
frm.set_query("assessment_group", function() {
return{
filters: {
"is_group": 1
}
};
});
},
refresh: function(frm) {
frm.disable_save();
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, {"doc": frm.doc}, true);
});
},
student: function(frm) {
if (frm.doc.student) {
frappe.call({
method:"erpnext.education.api.get_current_enrollment",
args: {
"student": frm.doc.student,
"academic_year": frm.doc.academic_year
},
callback: function(r) {
if(r){
$.each(r.message, function(i, d) {
if (frm.fields_dict.hasOwnProperty(i)) {
frm.set_value(i, d);
}
});
}
}
});
}
},
terms: function(frm) {
if(frm.doc.terms) {
return frappe.call({
method: 'erpnext.setup.doctype.terms_and_conditions.terms_and_conditions.get_terms_and_conditions',
args: {
template_name: frm.doc.terms,
doc: frm.doc
},
callback: function(r) {
frm.set_value("assessment_terms", r.message);
}
});
}
}
});

View File

@@ -0,0 +1,582 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2018-01-15 15:36:32.830069",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "student",
"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": "Student",
"length": 0,
"no_copy": 0,
"options": "Student",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "student_name",
"fieldtype": "Read Only",
"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": "Student Name",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 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": "program",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Program",
"length": 0,
"no_copy": 0,
"options": "Program",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "student_batch",
"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": "Batch",
"length": 0,
"no_copy": 0,
"options": "Student Batch Name",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "include_all_assessment",
"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": "Include All Assessment Group",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "show_marks",
"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": "Show Marks",
"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": "1",
"fieldname": "add_letterhead",
"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": "Add letterhead",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "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,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "assessment_group",
"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": "Assessment Group",
"length": 0,
"no_copy": 0,
"options": "Assessment Group",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "academic_year",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Academic Year",
"length": 0,
"no_copy": 0,
"options": "Academic Year",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "academic_term",
"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": "Academic Term",
"length": 0,
"no_copy": 0,
"options": "Academic Term",
"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": "add_letterhead",
"fieldname": "letter_head",
"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": "Letter Head",
"length": 0,
"no_copy": 0,
"options": "Letter Head",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_5",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Print Section",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "parents_meeting",
"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": "Total Parents Teacher Meeting",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "parents_attendance",
"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": "Attended by Parents",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "terms",
"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": "Terms",
"length": 0,
"no_copy": 0,
"options": "Terms and Conditions",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "assessment_terms",
"fieldtype": "Text Editor",
"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": "Assessment Terms",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 1,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 1,
"istable": 0,
"max_attachments": 0,
"modified": "2018-03-20 17:57:53.936119",
"modified_by": "Administrator",
"module": "Education",
"name": "Student Report Generation Tool",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 0,
"email": 0,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 0,
"read": 1,
"report": 0,
"role": "System Manager",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 1
}
],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0
}

View File

@@ -0,0 +1,91 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe, json
from frappe.model.document import Document
from erpnext.education.api import get_grade
from frappe.utils.pdf import get_pdf
from erpnext.education.report.course_wise_assessment_report.course_wise_assessment_report import get_formatted_result
from erpnext.education.report.course_wise_assessment_report.course_wise_assessment_report import get_child_assessment_groups
class StudentReportGenerationTool(Document):
pass
@frappe.whitelist()
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"],
filters={"student": doc.student, "docstatus": ('!=', 2), "academic_year": doc.academic_year})
if program_enrollment:
doc.batch = program_enrollment[0].student_batch_name
doc.student_name = program_enrollment[0].student_name
# get the assessment result of the selected student
values = get_formatted_result(doc, get_course=True, get_all_assessment_groups=doc.include_all_assessment)
assessment_result = values.get("assessment_result").get(doc.student)
courses = values.get("course_dict")
course_criteria = get_courses_criteria(courses)
# get the assessment group as per the user selection
if doc.include_all_assessment:
assessment_groups = get_child_assessment_groups(doc.assessment_group)
else:
assessment_groups = [doc.assessment_group]
# get the attendance of the student for that peroid of time.
doc.attendance = get_attendance_count(doc.students[0], doc.academic_year, doc.academic_term)
template = "erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.html"
base_template_path = "frappe/www/printview.html"
from frappe.www.printview import get_letter_head
letterhead = get_letter_head(frappe._dict({"letter_head": doc.letterhead}), not doc.add_letterhead)
html = frappe.render_template(template,
{
"doc": doc,
"assessment_result": assessment_result,
"courses": courses,
"assessment_groups": assessment_groups,
"course_criteria": course_criteria,
"letterhead": letterhead.content,
"add_letterhead": doc.add_letterhead if doc.add_letterhead else 0
})
final_template = frappe.render_template(base_template_path, {"body": html, "title": "Report Card"})
frappe.response.filename = "Report Card " + doc.students[0] + ".pdf"
frappe.response.filecontent = get_pdf(final_template)
frappe.response.type = "download"
def get_courses_criteria(courses):
course_criteria = frappe._dict()
for course in courses:
course_criteria[course] = [d.assessment_criteria for d in frappe.get_all("Course Assessment Criteria",
fields=["assessment_criteria"], filters={"parent": course})]
return course_criteria
def get_attendance_count(student, academic_year, academic_term=None):
if academic_year:
from_date, to_date = frappe.db.get_value("Academic Year", academic_year, ["year_start_date", "year_end_date"])
elif academic_term:
from_date, to_date = frappe.db.get_value("Academic Term", academic_term, ["term_start_date", "term_end_date"])
if from_date and to_date:
attendance = dict(frappe.db.sql('''select status, count(student) as no_of_days
from `tabStudent Attendance` where student = %s
and date between %s and %s group by status''',
(student, from_date, to_date)))
if "Absent" not in attendance.keys():
attendance["Absent"] = 0
if "Present" not in attendance.keys():
attendance["Present"] = 0
return attendance
else:
frappe.throw("Provide the academic year and set the starting and ending date.")

View File

@@ -0,0 +1,23 @@
/* eslint-disable */
// rename this file from _test_[name] to test_[name] to activate
// and remove above this line
QUnit.test("test: Student Report Generation Tool", function (assert) {
let done = assert.async();
// number of asserts
assert.expect(1);
frappe.run_serially([
// insert a new Student Report Generation Tool
() => frappe.tests.make('Student Report Generation Tool', [
// values to be set
{key: 'value'}
]),
() => {
assert.equal(cur_frm.doc.key, 'value');
},
() => done()
]);
});

View File

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
from __future__ import unicode_literals
import frappe
import unittest
class TestStudentReportGenerationTool(unittest.TestCase):
pass

View File

@@ -60,7 +60,7 @@ def execute(filters=None):
return columns, data, None, chart
def get_formatted_result(args, get_assessment_criteria=False, get_course=False):
def get_formatted_result(args, get_assessment_criteria=False, get_course=False, get_all_assessment_groups=False):
cond, cond1, cond2, cond3, cond4 = " ", " ", " ", " ", " "
args_list = [args.academic_year]
@@ -77,15 +77,9 @@ def get_formatted_result(args, get_assessment_criteria=False, get_course=False):
args_list.append(args.student_group)
create_total_dict = False
group_type = frappe.get_value("Assessment Group", args.assessment_group, "is_group")
if group_type:
from frappe.desk.treeview import get_children
assessment_groups = [d.get("value") for d in get_children("Assessment Group",
args.assessment_group) if d.get("value") and not d.get("expandable")]
cond3 = " and ar.assessment_group in (%s)"%(', '.join(['%s']*len(assessment_groups)))
else:
assessment_groups = [args.assessment_group]
cond3 = " and ar.assessment_group=%s"
assessment_groups = get_child_assessment_groups(args.assessment_group)
cond3 = " and ar.assessment_group in (%s)"%(', '.join(['%s']*len(assessment_groups)))
args_list += assessment_groups
if args.students:
@@ -156,6 +150,9 @@ def get_formatted_result(args, get_assessment_criteria=False, get_course=False):
# create the total of all the assessment groups criteria-wise
elif create_total_dict:
if get_all_assessment_groups:
formatted_assessment_result[result.student][result.course][result.assessment_group]\
[result.assessment_criteria] = assessment_criteria_details
if not formatted_assessment_result[result.student][result.course][args.assessment_group]:
formatted_assessment_result[result.student][result.course][args.assessment_group] = defaultdict(dict)
formatted_assessment_result[result.student][result.course][args.assessment_group]\
@@ -238,3 +235,15 @@ def get_chart_data(grades, criteria_list, kounter):
},
"type": 'bar',
}
def get_child_assessment_groups(assessment_group):
assessment_groups = []
group_type = frappe.get_value("Assessment Group", assessment_group, "is_group")
if group_type:
from frappe.desk.treeview import get_children
assessment_groups = [d.get("value") for d in get_children("Assessment Group",
assessment_group) if d.get("value") and not d.get("expandable")]
else:
assessment_groups = [assessment_group]
return assessment_groups

View File

@@ -27,26 +27,27 @@ def execute(filters=None):
course_dict = values.get("course_dict")
for student in args.students:
student_row = {}
student_row["student"] = student
student_row["student_name"] = student_details[student]
for course in course_dict:
scrub_course = frappe.scrub(course)
if assessment_group in assessment_result[student][course]:
student_row["grade_" + scrub_course] = assessment_result[student][course][assessment_group]["Total Score"]["grade"]
student_row["score_" + scrub_course] = assessment_result[student][course][assessment_group]["Total Score"]["score"]
if student_details.get(student):
student_row = {}
student_row["student"] = student
student_row["student_name"] = student_details[student]
for course in course_dict:
scrub_course = frappe.scrub(course)
if assessment_group in assessment_result[student][course]:
student_row["grade_" + scrub_course] = assessment_result[student][course][assessment_group]["Total Score"]["grade"]
student_row["score_" + scrub_course] = assessment_result[student][course][assessment_group]["Total Score"]["score"]
# create the list of possible grades
if student_row["grade_" + scrub_course] not in grades:
grades.append(student_row["grade_" + scrub_course])
# create the list of possible grades
if student_row["grade_" + scrub_course] not in grades:
grades.append(student_row["grade_" + scrub_course])
# create the dict of for gradewise analysis
if student_row["grade_" + scrub_course] not in course_wise_analysis[course]:
course_wise_analysis[course][student_row["grade_" + scrub_course]] = 1
else:
course_wise_analysis[course][student_row["grade_" + scrub_course]] += 1
# create the dict of for gradewise analysis
if student_row["grade_" + scrub_course] not in course_wise_analysis[course]:
course_wise_analysis[course][student_row["grade_" + scrub_course]] = 1
else:
course_wise_analysis[course][student_row["grade_" + scrub_course]] += 1
data.append(student_row)
data.append(student_row)
course_list = [d for d in course_dict]
columns = get_column(course_dict)

View File

@@ -23,11 +23,6 @@ frappe.ui.form.on('Consultation', {
patient: frm.doc.patient
},
callback: function (data) {
var age = null;
if(data.message.dob){
age = calculate_age(data.message.dob);
}
frappe.model.set_value(frm.doctype,frm.docname, "patient_age", age);
show_details(data.message);
}
});

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

@@ -1,8 +1,8 @@
frappe.views.calendar["Patient Appointment"] = {
field_map: {
"start": "start",
"end": "end",
"start": "appointment_date",
"end": "appointment_datetime",
"id": "name",
"title": "patient",
"allDay": "allDay"

View File

@@ -40,6 +40,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -70,6 +71,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -100,6 +102,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -126,10 +129,11 @@
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 1,
"report_hide": 0,
"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
},
{
@@ -192,6 +197,7 @@
"reqd": 0,
"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
},
{
@@ -254,6 +261,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -283,6 +291,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
},
{
@@ -343,6 +353,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -373,6 +384,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -403,6 +415,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -433,6 +446,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -464,6 +478,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -493,6 +508,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -524,6 +540,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -554,6 +571,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -585,6 +603,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -615,6 +634,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -645,6 +665,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -674,6 +695,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -704,6 +726,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -734,6 +757,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -765,6 +789,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@@ -796,6 +821,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}
],
@@ -810,7 +836,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-10-05 16:08:24.624644",
"modified": "2018-03-09 07:05:24.984224",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Physician",

View File

@@ -5,6 +5,7 @@
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
from frappe.utils import cstr
class VitalSigns(Document):
def on_submit(self):
@@ -27,22 +28,22 @@ def insert_vital_signs_to_medical_record(doc):
def delete_vital_signs_from_medical_record(doc):
medical_record_id = frappe.db.sql("select name from `tabPatient Medical Record` where reference_name=%s",(doc.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 set_subject_field(doc):
subject = " "
if(doc.temperature):
subject += "Temperature: \n"+ str(doc.temperature)+". "
subject += "Temperature: \n"+ cstr(doc.temperature)+". "
if(doc.pulse):
subject += "Pulse: \n"+ str(doc.pulse)+". "
subject += "Pulse: \n"+ cstr(doc.pulse)+". "
if(doc.respiratory_rate):
subject += "Respiratory Rate: \n"+ str(doc.respiratory_rate)+". "
subject += "Respiratory Rate: \n"+ cstr(doc.respiratory_rate)+". "
if(doc.bp):
subject += "BP: \n"+ str(doc.bp)+". "
subject += "BP: \n"+ cstr(doc.bp)+". "
if(doc.bmi):
subject += "BMI: \n"+ str(doc.bmi)+". "
subject += "BMI: \n"+ cstr(doc.bmi)+". "
if(doc.nutrition_note):
subject += "Note: \n"+ str(doc.nutrition_note)+". "
subject += "Note: \n"+ cstr(doc.nutrition_note)+". "
return subject

View File

@@ -204,7 +204,7 @@ doc_events = {
'Address': {
'validate': 'erpnext.regional.india.utils.validate_gstin_for_india'
},
('Sales Invoice', 'Purchase Invoice'): {
('Sales Invoice', 'Purchase Invoice', 'Delivery Note'): {
'validate': 'erpnext.regional.india.utils.set_place_of_supply'
}
}

View File

@@ -24,6 +24,7 @@ cur_frm.cscript.refresh = function(doc,cdt,cdn){
}
cur_frm.cscript.kra_template = function(doc, dt, dn) {
doc.goals = [];
erpnext.utils.map_current_doc({
method: "erpnext.hr.doctype.appraisal.appraisal.fetch_appraisal_template",
source_name: cur_frm.doc.kra_template,

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