Compare commits

..

174 Commits

Author SHA1 Message Date
Nabin Hait
537db4c2c7 Merge branch 'hotfix' 2017-12-25 13:38:06 +05:30
Nabin Hait
f4c5cf5bd0 bumped to version 9.2.24 2017-12-25 14:08:05 +06:00
rohitwaghchaure
bd5e01b09b [fix] Shipping address not fetch from purchase order in to purchase invoice & receipt. (#12134) 2017-12-25 11:28:07 +05:30
rohitwaghchaure
d8c6449f3a [Fix] Bom raw materials not in order in the stock entry (#12149) 2017-12-25 11:26:40 +05:30
rohitwaghchaure
75789b65c2 [Fix] Sales payment summary report (#12151) 2017-12-25 11:26:15 +05:30
rohitwaghchaure
443691aaf8 [Fix] Allow to change exchange rate in the payment entry if allow stale is enabled (#12128) 2017-12-22 10:59:01 +05:30
rohitwaghchaure
174900506e [HotFix] Validation issue for subcontract stock entry (#12127)
* [Fix] Validation issue for subcontract stock entry

* Update stock_entry.py
2017-12-21 11:28:01 +05:30
rohitwaghchaure
84da00da2f Allow to add items in manufacturing process which are not part of bom items (#12110) 2017-12-20 12:06:09 +05:30
rohitwaghchaure
78a17355be [fix] Item search in POS (#12037) 2017-12-15 15:38:12 +05:30
Nabin Hait
d257af910b Merge branch 'hotfix' 2017-12-15 12:53:55 +05:30
Nabin Hait
2f22d2b307 bumped to version 9.2.23 2017-12-15 13:23:54 +06:00
Pawan Mehta
d6cb617520 Fix 11948 - Sales Payment Summary (#11950)
* [fix] #11948

* [fix] #11948

* [fix] #11948

* codacy issues
2017-12-14 18:04:31 +05:30
Nabin Hait
aaf378e340 Validate numeric attribute value based on range defined in template (#11981) 2017-12-13 18:40:52 +05:30
Nabin Hait
96d6498226 Merge branch 'hotfix' 2017-12-12 19:17:51 +05:30
Nabin Hait
66456dae34 bumped to version 9.2.22 2017-12-12 19:47:51 +06:00
Nabin Hait
af9bdfeaa3 Fixed calculation of taxes and totals if tax is entered as Actual, for Deduction or valuation (#11965) 2017-12-12 18:50:05 +05:30
Nabin Hait
aab1182c73 Update stock_entry.js 2017-12-12 18:45:39 +05:30
Nabin Hait
de1e29bf1b Production Order fixes (#11951)
* Production Order from Sales Order fixes: Validate SO and set required items on save

* Codacy fixes
2017-12-12 13:22:48 +05:30
pawan
1892454036 Add Total Row 2017-12-11 17:48:56 +05:30
Nabin Hait
84a44f7758 Merge branch 'hotfix' 2017-12-07 12:03:40 +05:30
Nabin Hait
6674ba8bd1 bumped to version 9.2.21 2017-12-07 12:33:40 +06:00
Nabin Hait
5de499e5d5 Minor cleanups 2017-12-07 12:01:06 +05:30
pawan
271b7cd4f9 codacy issues 2017-12-07 12:01:00 +05:30
pawan
19f09b0b69 fix codacy issues 2017-12-07 12:00:06 +05:30
pawan
d8e91982ca Fixed Merge conflict 2017-12-07 12:00:01 +05:30
Nabin Hait
7ff6e378dd Merge branch 'hotfix' 2017-12-06 14:17:14 +05:30
Nabin Hait
7de5d3bb1d bumped to version 9.2.20 2017-12-06 14:47:13 +06:00
rohitwaghchaure
1b16bca843 [minor] Escape special characters (#11855) 2017-12-06 13:16:06 +05:30
tundebabzy
6a418f2a9b change Purchase Taxes and Charges default to 'Total' (#11857) 2017-12-06 13:15:33 +05:30
rohitwaghchaure
d52c64ff11 [fix] Show total for opening and closing dr/cr (#11860) 2017-12-06 13:14:28 +05:30
rohitwaghchaure
3a5ca927e7 [Fix] Asset depreciations and balances report showing wrong accumulated depreciation amount if multiple asset against same asset category (#11848)
* [Fix] Asset depreciations and balances report showing wrong accumulated depreciation amount if multiple asset against same asset category

* Update asset_depreciations_and_balances.py
2017-12-04 19:29:03 +05:30
rohitwaghchaure
148fccd45a [Fix] Wrong value showing in the email digest (#11840) 2017-12-04 13:36:01 +05:30
tundebabzy
3061fc92fd Batch Stock Items, having serial number can't be moved without inserting Serial Number (#11792) (#11813)
* if doctype is batch, add extra information to args

* automatically fetch serial numbers if possible

* take advantage of changes in make_stock_entry

* code clean up

* PEP 8 compliance

* fix bug that clears serial number
2017-12-04 11:23:21 +05:30
tundebabzy
1fb285c165 hide html example in print (#11830) 2017-12-04 11:13:36 +05:30
Saurabh
b36dc5e906 Merge branch 'hotfix' 2017-12-01 16:22:43 +05:30
Saurabh
a067ddbc20 bumped to version 9.2.19 2017-12-01 16:52:43 +06:00
Jamsheer
f4d9af1ab9 Fix Patch - remove company from patient (#11819) 2017-12-01 16:10:39 +05:30
rohitwaghchaure
b1ac979ac5 [fix] Do not allow zero valuation rate for serial no and fetch previous valuation rate for serial no (#11817) 2017-12-01 16:09:02 +05:30
Nabin Hait
7a294e6ef5 Update asset_category.json 2017-11-30 18:02:22 +05:30
Nabin Hait
5e801955f1 Update asset_category.json 2017-11-30 18:01:56 +05:30
Saurabh
aa25e95510 Merge branch 'hotfix' 2017-11-30 16:41:46 +05:30
Saurabh
f9509a084a bumped to version 9.2.18 2017-11-30 17:11:46 +06:00
Faris Ansari
ec3be9eebf [hotfix] Party Type name (#11797) 2017-11-30 15:53:39 +05:30
Nabin Hait
c5e0d22464 Update set_delivery_date_in_so_item.py 2017-11-30 15:52:47 +05:30
Rushabh Mehta
0154538c06 [fix] [minor] pos.js 2017-11-29 16:42:02 +05:30
rohitwaghchaure
1b344ca81e [Fix] POS not loading if pos profile not defined (#11778) 2017-11-29 16:21:51 +05:30
rohitwaghchaure
4a15711b04 Merge pull request #11768 from tundebabzy/issue-11749
add missing field and value parameters
2017-11-29 11:22:20 +05:30
tunde
0d82b6979e add missing field and value parameters 2017-11-28 23:30:03 +01:00
tundebabzy
bc7c387a0d set read only property properly (#11761) 2017-11-28 22:40:05 +05:30
Nabin Hait
35cd1d325f [fix] Set GST State code based on state, even if GSTIN not mentioned (#11755) 2017-11-28 13:01:01 +05:30
Saurabh
7b833802a9 Merge branch 'hotfix' 2017-11-28 11:00:17 +05:30
Saurabh
d86ace41a1 bumped to version 9.2.17 2017-11-28 11:30:17 +06:00
Jamsheer
b488475d92 Remove Company from Patient - Patches Added (#11716)
* Remove Company from Patient - Patches Added

* Update patient DOB field label to Date of birth

* Patient marital status default null

* Update patient.py
2017-11-28 10:47:06 +05:30
Saurabh
8eda0cc8ba [fix] validate bom if order type is subcontracting (#11705)
* [fix] validate bom if order type is subcontracting

* [fix] moved validation to server side
2017-11-28 10:41:35 +05:30
Saurabh
9d0092f89a [fix] pull source warehouse from production order child table (#11718) 2017-11-27 12:04:41 +05:30
Shreya Shah
e3d6d21ec5 [Fix] Item name and description in production order (#11723)
* fetch item name and description from bom

* Update production_order.py

* patch added

* Update set_item_name_in_production_order.py
2017-11-27 12:02:13 +05:30
Saurabh
ab5e77ecf1 [fix] do not pull disabled pos profiles (#11733) 2017-11-27 11:26:13 +05:30
Saurabh
41f60546a1 [fix] do not allow user to create party type (#11706) 2017-11-23 18:02:51 +05:30
Nabin Hait
cda4d50063 Fixed reserved qty for production logic and patch for reposting (#11691) 2017-11-23 13:05:43 +05:30
Zarrar
a90274fed9 linking issue in dashboard (#11701) 2017-11-23 12:19:40 +05:30
Jamsheer
1ce56316ea Populate patient_name in Healthcare Doctypes (#11690)
* On Cancel Consultation - Open Appointment - Delete Medical Record

* Add Filter on Account Selection - is_group: 0

* Patient Medical Record - List view Fixes

* Update consultation.py

* Set Appointment Refrence in Vital Signs

* Add Other in Gender Selection

* Populate patient_name in Healthcare Doctypes
2017-11-23 12:18:43 +05:30
Saurabh
7cf945c975 Merge branch 'hotfix' 2017-11-22 17:54:18 +05:30
Saurabh
4bc12b68e4 bumped to version 9.2.16 2017-11-22 18:24:18 +06:00
rohitwaghchaure
4dc5f0efaf [Fix] Item details not fetching if item has no default bom (#11688) 2017-11-22 15:21:47 +05:30
Nabin Hait
96abfd2ab9 [fix] In payment entry, run some events serially to avoid async issue 2017-11-22 15:13:16 +05:30
Makarand Bauskar
75443a94ee [minor] set the pos profile name while creating demo (#11664) 2017-11-21 16:12:40 +05:30
Nabin Hait
cc884578b5 Update sales_order.py 2017-11-21 12:24:03 +05:30
rohitwaghchaure
179e0c1d8d Added party name in accounts receivable/payable report (#11656) 2017-11-20 11:18:55 +05:30
rohitwaghchaure
34d6340be6 Merge pull request #11647 from rohitwaghchaure/pos_selling_price_issue
[fix] Price list not loaded from pos profile, auto set outstanding amount in the mode of payment
2017-11-18 21:33:32 +05:30
Rohit Waghchaure
77940493a8 [fix] Price list not loaded from pos profile, auto set outstanding amount in the mode of payment 2017-11-18 19:06:31 +05:30
Saurabh
a5b53e9480 Merge branch 'hotfix' 2017-11-17 14:55:23 +05:30
Saurabh
f773af6053 bumped to version 9.2.15 2017-11-17 15:25:23 +06:00
Saurabh
119a50e228 Merge pull request #11630 from saurabh6790/domain_settings_fix
[fix] set default language in local
2017-11-17 14:54:38 +05:30
Saurabh
11ec2c50e0 [fix] set default language in local 2017-11-17 14:51:08 +05:30
Saurabh
1e74519726 Merge branch 'hotfix' 2017-11-17 14:01:30 +05:30
Saurabh
05ed86a00e bumped to version 9.2.14 2017-11-17 14:31:29 +06:00
Saurabh
d40ae81fc9 Merge pull request #11627 from rohitwaghchaure/pos_redirect_issue
[fix] POS redirect issue
2017-11-17 13:55:10 +05:30
Rohit Waghchaure
44f7b157ff [fix] POS redirect issue 2017-11-17 13:52:11 +05:30
Saurabh
3499ba08df [fix] do not translate domains while creating db record (#11616) 2017-11-17 12:29:26 +05:30
rohitwaghchaure
51a397c97f [fix] Valuation rate in stock entry and code cleanup (#11614) 2017-11-16 18:23:16 +05:30
Manas Solanki
bb34c57603 link the address and contact with the sales partner (#11592) 2017-11-16 18:10:04 +05:30
tundebabzy
f7e6934d7c handle None case in update_reserved_qty_for_production (#11593) 2017-11-16 14:13:49 +05:30
rohitwaghchaure
21cbbae88f [fix] Payment reconcillation showing linked journal entries (#11611) 2017-11-16 14:05:57 +05:30
Nabin Hait
94704beba3 Merge branch 'hotfix' 2017-11-15 14:08:17 +05:30
Nabin Hait
429e5d57d5 bumped to version 9.2.13 2017-11-15 14:38:17 +06:00
Jamsheer
0abec034df Healthcare hotfix (#11586)
* On Cancel Consultation - Open Appointment - Delete Medical Record

* Add Filter on Account Selection - is_group: 0

* Patient Medical Record - List view Fixes

* Update consultation.py
2017-11-15 13:53:50 +05:30
Umair Sayed
3a9ca883b9 Update party.py (#11584) 2017-11-15 13:44:04 +05:30
Manas Solanki
bf59b5927f make route from item code if item name is None (#11579) 2017-11-15 10:55:22 +05:30
Jamsheer
bab226698f Healthcare hotfix (#11574)
* Patient dashboard - Vital Signs

* Remove submit validation in Consultation

* Physician Schedule - Add Time Slots - Fix

* Patient Appointment - Client side - fixes
2017-11-15 09:47:00 +05:30
rohitwaghchaure
43edd5d03c Employee loan fixes (#11495)
* Employee loan fixes

* Update update_employee_loan_details.py
2017-11-14 17:59:20 +05:30
Nabin Hait
3f83afe4e1 Merge branch 'hotfix' 2017-11-14 17:48:42 +05:30
Nabin Hait
ea3e6b93a7 bumped to version 9.2.12 2017-11-14 18:18:42 +06:00
Nabin Hait
42274a4591 Delete healthcare domain items (#11567) 2017-11-14 17:15:11 +05:30
Nabin Hait
66f460ffbc Merge branch 'hotfix' 2017-11-14 13:58:37 +05:30
Nabin Hait
0590d1da05 bumped to version 9.2.11 2017-11-14 14:28:37 +06:00
Rushabh Mehta
98aa581864 [fix] default tax only on insert (#11544)
* [fix] default tax only on insert

* [fix] default tax only on insert

* [fix] default tax only on insert
2017-11-14 09:32:32 +05:30
Nabin Hait
758c389ef3 Merge branch 'hotfix' 2017-11-13 15:10:16 +05:30
Nabin Hait
58ab203fc0 bumped to version 9.2.10 2017-11-13 15:40:16 +06:00
Nabin Hait
6605919ecd GL Entries on sale of an asset (#11538) 2017-11-13 15:06:35 +05:30
Saurabh
feeb47dbbe [fix] if not students in student groups then raise exception (#11537) 2017-11-13 13:52:58 +05:30
Nabin Hait
deeb1380b1 Ignore paid credit note in outstanding invoices in Payment Entry (#11534) 2017-11-13 13:52:05 +05:30
Saurabh
0f86d86e27 [fix] validate party account (#11517) 2017-11-10 19:21:09 +05:30
Prateeksha Singh
731b66b788 remove erroneous column breaks (#11523) 2017-11-10 18:53:52 +05:30
Saurabh
241139001e Merge branch 'hotfix' 2017-11-10 15:53:43 +05:30
Saurabh
a10cd10640 bumped to version 9.2.9 2017-11-10 16:23:43 +06:00
Saurabh
44ef8654f9 Merge pull request #11510 from rohitwaghchaure/issue_11502
Add item directly in the cart only if serial no, batch, barcode has enter in the search field
2017-11-10 15:51:14 +05:30
Saurabh
71862f9024 Merge pull request #11509 from saurabh6790/bom_search_query_fix
[fix] query param fixes
2017-11-10 15:50:55 +05:30
Rohit Waghchaure
a5e3c3a79f Add item directly in the cart only if serial no, batch, barcode has enter in the search field 2017-11-10 15:29:26 +05:30
rohitwaghchaure
cc97ec9202 [hotfix] Salary slip, leave considered in amount calculation even if depends on lwp is disabled in salary slip (#11507) 2017-11-10 15:06:58 +05:30
Saurabh
022ab63a0f [fix] query param fixes 2017-11-10 15:06:02 +05:30
Saurabh
cdf8016bcd Merge branch 'hotfix' 2017-11-10 13:15:04 +05:30
Saurabh
18c8cf965f bumped to version 9.2.8 2017-11-10 13:45:04 +06:00
Nabin Hait
8e3da7f70e Update test_assessment_plan.js 2017-11-10 10:59:17 +05:30
Nabin Hait
887285ed1a Update test_assessment_plan.js 2017-11-10 10:59:07 +05:30
Manas Solanki
aeb0026354 commits from develop merged PR's (#11491)
* better student search queries and minor fixes in the student group

* remove the print option for the tools

* fixes for the chart

* minor fixes in the fee module for print and permission, delete redundant doctype

* set the naming series and independent dob validation
2017-11-10 10:58:43 +05:30
rohitwaghchaure
1ce48e7032 [fix] POS profile patch (#11501) 2017-11-10 10:53:12 +05:30
Faris Ansari
99e31f97b8 set default params for paging (#11500) 2017-11-10 10:50:49 +05:30
Faris Ansari
4a864c1eea [fix] Update bom item description (#11498)
* [fix] Update bom item description

* Update item.py
2017-11-09 19:01:21 +05:30
Prateeksha Singh
3e998bccba Merge pull request #11490 from pratu16x7/hotfix
[minor][hotfix] naming_series variable assignment
2017-11-08 17:22:49 +05:30
pratu16x7
40016372c6 [minor][hotfix] naming_series variable assignment 2017-11-08 16:30:15 +05:30
Saurabh
af22f84809 Merge branch 'hotfix' 2017-11-08 15:07:33 +05:30
Saurabh
3894a5ed94 bumped to version 9.2.7 2017-11-08 15:37:33 +06:00
Saurabh
045b2877b7 [fix] remove warehouse from Stock Settings if warehouse wont exists (#11487) 2017-11-08 14:57:03 +05:30
Saurabh
148b62a206 Merge pull request #11486 from saurabh6790/patch_fixes_
[fix] catch link validation exception in POS profile and reload fees …
2017-11-08 14:48:33 +05:30
Saurabh
d2cef208fe [fix] catch link validation exception in POS profile and reload fees doctype 2017-11-08 14:44:43 +05:30
Saurabh
4c617d6496 Merge branch 'staging' 2017-11-08 12:20:46 +05:30
Saurabh
f985ae1379 bumped to version 9.2.6 2017-11-08 12:50:46 +06:00
Saurabh
98aa544f25 Merge branch 'master' into staging 2017-11-08 12:18:50 +05:30
Saurabh
6ad1082433 Merge branch 'hotfix' 2017-11-08 12:12:37 +05:30
Saurabh
db781e607a bumped to version 9.2.5 2017-11-08 12:42:37 +06:00
rohitwaghchaure
521606e433 Merge pull request #11398 from rohitwaghchaure/item_variants_donot_copy_option
[enhance] In item variants settings added provision, do not update the variants of variants from the template but will copy the value while making new variant aginst the template
2017-11-08 11:49:24 +05:30
Rohit Waghchaure
acc8995c48 [enhance] In item variants settings added provision, do not update the fields of variants from the template but will copy the value while making new variant aginst the template 2017-11-08 11:39:08 +05:30
rohitwaghchaure
f688af3809 [fix] Offline pos name is not defined issue in the POS (#11469) 2017-11-08 11:33:39 +05:30
rohitwaghchaure
9f2a27c99c Merge pull request #11477 from rohitwaghchaure/pos_profile_test_cases
[fix] POS Profile test cases
2017-11-07 16:35:52 +05:30
rohitwaghchaure
6058dcc2ce Merge pull request #11470 from rohitwaghchaure/pos_online_invalid_grand_total_issue
[Fix] Fast clicking on an item, showing invalid grand total and quantity in the POS cart
2017-11-07 16:19:51 +05:30
Rohit Waghchaure
35fc45eff9 [fix] POS Profile test cases 2017-11-07 10:43:16 +05:30
Rohit Waghchaure
57cc924d29 [Fix] Fast clicking on an item, showing invalid grand total and quantity in the POS cart 2017-11-06 18:42:37 +05:30
rohitwaghchaure
adbbb0b0f3 Merge pull request #11364 from manassolanki/set-pos-profile
set the pos profile in the sales invoice
2017-11-06 14:08:59 +05:30
Manas Solanki
40ef7e7039 patch for renaming the pos profile and setting the pos profile name 2017-11-06 13:53:52 +05:30
Manas Solanki
b1616a0cb3 changes in thepos profile 2017-11-06 13:53:52 +05:30
Manas Solanki
3f0dfd720f set the pos profile in the sales invoice 2017-11-06 13:53:52 +05:30
Saurabh
e850655c1d Merge branch 'master' into staging 2017-11-03 16:56:24 +05:30
Saurabh
5647bf081a Merge branch 'hotfix' 2017-11-03 16:56:23 +05:30
Saurabh
56cb0aa9c1 bumped to version 9.2.4 2017-11-03 17:26:23 +06:00
rohitwaghchaure
7677ff00a2 [hotfix] User not able to edit exchange rate even if Allow Stale Exchange Rates is disabled in the accounts settings (#11409) 2017-11-02 18:12:14 +05:30
Saurabh
62fd4007b0 Merge branch 'master' into staging 2017-11-02 12:14:42 +05:30
Saurabh
75f3f81a9b Merge branch 'hotfix' 2017-11-02 12:14:41 +05:30
Saurabh
870ce3cfea bumped to version 9.2.3 2017-11-02 12:44:40 +06:00
Saurabh
0ad2cc3def Merge pull request #11403 from tundebabzy/issue-11402
Error In Employee Loan Form (#11402)
2017-11-02 12:09:54 +05:30
Saurabh
00f6c2d61d Merge pull request #11417 from rohitwaghchaure/issue_not_save_v9
[Fix] Customer is manadatory even if customer has selected in the Issue
2017-11-02 12:07:32 +05:30
Saurabh
38008f8daa Merge pull request #11406 from rohitwaghchaure/payment_entry_differnece_amount_issue
[Fix] Wrong difference amount in the payment entry for the internal transfer type
2017-11-02 12:07:14 +05:30
Saurabh
afb63af3b6 Merge pull request #11397 from rohitwaghchaure/delivery_note_issue_from_so
[Fix] Getting an error while making delivery note from sales order and sales order has no item code
2017-11-02 12:06:08 +05:30
Rohit Waghchaure
816ce33daf [Fix] Customer is manadatory even if customer has selected in the Issue 2017-11-01 19:02:09 +05:30
Rohit Waghchaure
99748dbacf [Fix] Wrong difference amount in the payment entry for the internal transfer type 2017-11-01 11:45:02 +05:30
tunde
31287b00a6 call get_employee_loan_application only when appropriate 2017-10-31 18:10:17 +01:00
Rohit Waghchaure
5ec9f6930b [Fix] Getting an error while making delivery note from sales order and sales order has no item code 2017-10-31 15:26:56 +05:30
Faris Ansari
40611e4f69 [fix] hub get_item_details (#11383) 2017-10-31 13:00:09 +05:30
Saurabh
dd0bdc7fa6 Merge pull request #11356 from tundebabzy/issue-11355
fix object has not attribute 'is_item_from_hub'
2017-10-31 12:23:09 +05:30
tunde
bbce7b7e5d get attribute with get method 2017-10-26 14:31:13 +01:00
Nabin Hait
c799a22d55 Merge branch 'master' into staging 2017-10-26 14:35:34 +05:30
Saurabh
b445633e56 Merge branch 'master' into staging 2017-10-26 09:59:22 +05:30
Nabin Hait
6500af9aa2 Merge branch 'develop' into staging 2017-10-25 14:25:06 +05:30
Nabin Hait
8f2500083c Merge branch 'master' into develop 2017-10-25 14:10:39 +05:30
Nabin Hait
cd3dbcb2ef Fixed Merge Conflict 2017-10-25 14:07:25 +05:30
tundebabzy
bafcd7418a Add Bundle Description Field To Product Bundle (#11122)
* add description field that shows in list view

* description field should be simply `description`
2017-10-25 12:22:08 +05:30
Makarand Bauskar
085b4842a1 [minor] minor fixes in get_company_details for Hub page (#11168) 2017-10-25 12:19:10 +05:30
Doridel Cahanap
49a7bde6e2 [minor] Label for Training Event in Training Program Dashboard (#11280) 2017-10-25 12:15:17 +05:30
Pawan Mehta
07ab4622e8 [fix] #9824 - Calculate costing amount even if billable is unchecked (#11310)
* [fix] #9824

* fix code
2017-10-25 11:55:49 +05:30
Narciso E. Núñez Arias
47caf51efe [docs] Translate the Projects section of the Manual to Spanish (#11319)
* [docs] Translate projects module. Add index page

* [docs] Translate activity cost page from projects module.

* [docs] Translate activity type page from projects module.

* [docs] Translate the Project Costing article in project module

* [docs] Translate the Project page in projects module

* [docs] Translate the Task page in projects module

* [docs] Translate the Time Log Batch page in projects module
2017-10-25 11:53:10 +05:30
Charles-Henri Decultot
7862eb444f [Hotfix] Addition of an empty tax group in the french CoA (#11306) 2017-10-25 11:44:46 +05:30
Neil Trini Lasrado
1f99bea6ce Pass sender as contact email in Opportunity (#11308)
Always pass sender as the contact email while creating an opportunity for a website enquiry.
2017-10-25 11:44:12 +05:30
Manas Solanki
a5eee4629f Fix UI tests (#11309)
* decrease the timeout

* delete the duplicate test
2017-10-25 11:42:22 +05:30
vishalseshagiri
5c5a853894 Update customer_group.py (#11270)
Minor syntactical error !
2017-10-23 11:35:49 +05:30
Doridel Cahanap
b06f155ceb [minor] Set Quick Entry to False in Training Event (#11279) 2017-10-23 11:35:12 +05:30
153 changed files with 2994 additions and 1322 deletions

View File

@@ -4,7 +4,7 @@ import inspect
import frappe
from erpnext.hooks import regional_overrides
__version__ = '9.2.2'
__version__ = '9.2.24'
def get_default_company(user=None):
'''Get default company for user'''

View File

@@ -851,7 +851,7 @@
"4457-Taxes sur le chiffre d'affaires collect\u00e9es par l'entreprise": {
"44571-TVA collect\u00e9e": {
"account_type": "Tax",
"tax_rate": 20.0
"is_group": 1
},
"44578-Taxes assimil\u00e9es \u00e0 la TVA": {}
},

View File

@@ -151,11 +151,14 @@ def restore_asset(asset_name):
asset.set_status()
@frappe.whitelist()
def get_gl_entries_on_asset_disposal(asset, selling_amount=0):
def get_gl_entries_on_asset_disposal(asset, is_sale=False):
fixed_asset_account, accumulated_depr_account, depr_expense_account = get_depreciation_accounts(asset)
disposal_account, depreciation_cost_center = get_disposal_account_and_cost_center(asset.company)
accumulated_depr_amount = flt(asset.gross_purchase_amount) - flt(asset.value_after_depreciation)
expense_account, cost_center = get_disposal_account_and_cost_center(asset.company)
if is_sale:
expense_account = depr_expense_account
gl_entries = [
{
"account": fixed_asset_account,
@@ -169,14 +172,12 @@ def get_gl_entries_on_asset_disposal(asset, selling_amount=0):
}
]
profit_amount = flt(selling_amount) - flt(asset.value_after_depreciation)
if flt(asset.value_after_depreciation) and profit_amount:
debit_or_credit = "debit" if profit_amount < 0 else "credit"
if flt(asset.value_after_depreciation):
gl_entries.append({
"account": disposal_account,
"cost_center": depreciation_cost_center,
debit_or_credit: abs(profit_amount),
debit_or_credit + "_in_account_currency": abs(profit_amount)
"account": expense_account,
"cost_center": cost_center,
"debit": flt(asset.value_after_depreciation),
"debit_in_account_currency": flt(asset.value_after_depreciation)
})
return gl_entries

View File

@@ -188,7 +188,6 @@ class TestAsset(unittest.TestCase):
asset.load_from_db()
depr_entry = asset.get("schedules")[0].journal_entry
self.assertFalse(depr_entry)
def test_scrap_asset(self):
asset = frappe.get_doc("Asset", "Macbook Pro 1")
@@ -234,8 +233,9 @@ class TestAsset(unittest.TestCase):
expected_gle = (
("_Test Accumulated Depreciations - _TC", 30000.0, 0.0),
("_Test Depreciations - _TC", 70000.0, 0.0),
("_Test Fixed Asset - _TC", 0.0, 100000.0),
("_Test Gain/Loss on Asset Disposal - _TC", 45000.0, 0.0),
("_Test Gain/Loss on Asset Disposal - _TC", 0.0, 25000.0),
("Debtors - _TC", 25000.0, 0.0)
)

View File

@@ -59,7 +59,7 @@
"label": "Depreciation Method",
"length": 0,
"no_copy": 0,
"options": "\nStraight Line\nDouble Declining Balance",
"options": "\nStraight Line\nDouble Declining Balance\nManual",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -228,7 +228,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-02-17 16:09:52.955332",
"modified": "2017-11-30 16:09:52.955332",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Asset Category",
@@ -284,4 +284,4 @@
"sort_order": "DESC",
"track_changes": 0,
"track_seen": 0
}
}

View File

@@ -11,36 +11,6 @@
"doctype": "DocType",
"editable_grid": 0,
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": "50%",
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -438,7 +408,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 3,
"modified": "2017-06-13 14:28:56.667292",
"modified": "2017-11-10 18:44:44.081464",
"modified_by": "Administrator",
"module": "Accounts",
"name": "C-Form",

View File

@@ -252,22 +252,25 @@ frappe.ui.form.on('Payment Entry', {
date: frm.doc.posting_date
},
callback: function(r, rt) {
console.log(r, rt);
if(r.message) {
if(frm.doc.payment_type == "Receive") {
frm.set_value("paid_from", r.message.party_account);
frm.set_value("paid_from_account_currency", r.message.party_account_currency);
frm.set_value("paid_from_account_balance", r.message.account_balance);
} else if (frm.doc.payment_type == "Pay"){
frm.set_value("paid_to", r.message.party_account);
frm.set_value("paid_to_account_currency", r.message.party_account_currency);
frm.set_value("paid_to_account_balance", r.message.account_balance);
}
frm.set_value("party_balance", r.message.party_balance);
frm.events.get_outstanding_documents(frm);
frm.events.hide_unhide_fields(frm);
frm.events.set_dynamic_labels(frm);
frm.set_party_account_based_on_party = false;
frappe.run_serially([
() => {
if(frm.doc.payment_type == "Receive") {
frm.set_value("paid_from", r.message.party_account);
frm.set_value("paid_from_account_currency", r.message.party_account_currency);
frm.set_value("paid_from_account_balance", r.message.account_balance);
} else if (frm.doc.payment_type == "Pay"){
frm.set_value("paid_to", r.message.party_account);
frm.set_value("paid_to_account_currency", r.message.party_account_currency);
frm.set_value("paid_to_account_balance", r.message.account_balance);
}
},
() => frm.set_value("party_balance", r.message.party_balance),
() => frm.events.get_outstanding_documents(frm),
() => frm.events.hide_unhide_fields(frm),
() => frm.events.set_dynamic_labels(frm),
() => { frm.set_party_account_based_on_party = false; }
]);
}
}
});
@@ -405,7 +408,7 @@ frappe.ui.form.on('Payment Entry', {
}
// Make read only if Accounts Settings doesn't allow stale rates
frm.set_df_property("source_exchange_rate", "read_only", erpnext.stale_rate_allowed());
frm.set_df_property("source_exchange_rate", "read_only", erpnext.stale_rate_allowed() ? 0 : 1);
},
target_exchange_rate: function(frm) {
@@ -426,7 +429,7 @@ frappe.ui.form.on('Payment Entry', {
frm.set_paid_amount_based_on_received_amount = false;
// Make read only if Accounts Settings doesn't allow stale rates
frm.set_df_property("target_exchange_rate", "read_only", erpnext.stale_rate_allowed());
frm.set_df_property("target_exchange_rate", "read_only", erpnext.stale_rate_allowed() ? 0 : 1);
},
paid_amount: function(frm) {
@@ -648,13 +651,13 @@ frappe.ui.form.on('Payment Entry', {
set_difference_amount: function(frm) {
var unallocated_amount = 0;
var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [],
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 total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [],
function(d) { return flt(d.amount) }));
if(frm.doc.total_allocated_amount < party_amount) {
if(frm.doc.payment_type == "Receive") {
unallocated_amount = party_amount - (frm.doc.total_allocated_amount - total_deductions);

View File

@@ -26,7 +26,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Series",
"length": 0,
@@ -432,7 +432,7 @@
"options": "<pre><h5>Message Example</h5>\n\n&lt;p&gt;Dear {{ doc.contact_person }},&lt;/p&gt;\n\n&lt;p&gt;Requesting payment for {{ doc.doctype }}, {{ doc.name }} for {{ doc.grand_total }}.&lt;/p&gt;\n\n&lt;a href=\"{{ payment_url }}\"&gt; click here to pay &lt;/a&gt;\n\n</pre>\n",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
@@ -728,7 +728,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-06-13 14:29:20.388372",
"modified": "2017-12-02 15:50:41.775006",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Request",

View File

@@ -1,5 +1,6 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "PCE/.###",
@@ -12,34 +13,7 @@
"engine": "InnoDB",
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"oldfieldtype": "Column Break",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -50,6 +24,7 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Transaction Date",
@@ -69,6 +44,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -79,6 +55,7 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Posting Date",
@@ -98,6 +75,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -108,6 +86,7 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Closing Fiscal Year",
@@ -128,6 +107,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -138,6 +118,7 @@
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Amended From",
@@ -158,6 +139,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -168,6 +150,7 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Company",
@@ -188,6 +171,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -198,6 +182,7 @@
"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,
@@ -215,6 +200,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -226,6 +212,7 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Closing Account Head",
@@ -246,6 +233,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -256,6 +244,7 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Remarks",
@@ -275,18 +264,18 @@
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-file-text",
"idx": 1,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 1,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2016-11-07 05:32:15.691681",
"modified": "2017-11-10 18:41:10.881530",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Period Closing Voucher",
@@ -302,7 +291,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@@ -323,7 +311,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@@ -339,8 +326,10 @@
"read_only": 0,
"read_only_onload": 0,
"search_fields": "posting_date, fiscal_year",
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "closing_account_head",
"track_changes": 0,
"track_seen": 0
}

View File

@@ -24,11 +24,11 @@ frappe.ui.form.on("POS Profile", "onload", function(frm) {
frappe.ui.form.on('POS Profile', {
setup: function(frm) {
frm.set_query("online_print_format", function() {
frm.set_query("print_format_for_online", function() {
return {
filters: [
['Print Format', 'doc_type', '=', 'Sales Invoice'],
['Print Format', 'print_format_type', '!=', 'Js'],
['Print Format', 'print_format_type', '=', 'Server'],
]
};
});

View File

@@ -3,7 +3,7 @@
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "hash",
"autoname": "field:pos_profile_name",
"beta": 0,
"creation": "2013-05-24 12:15:51",
"custom": 0,
@@ -11,6 +11,96 @@
"doctype": "DocType",
"editable_grid": 0,
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"fieldname": "disabled",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Disabled",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_2",
"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,
"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": "pos_profile_name",
"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": "POS Profile Name",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -112,9 +202,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "update_stock",
"fieldname": "warehouse",
"fieldtype": "Link",
"fieldname": "ignore_pricing_rule",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -122,13 +211,11 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Warehouse",
"label": "Ignore Pricing Rule",
"length": 0,
"no_copy": 0,
"oldfieldname": "warehouse",
"oldfieldtype": "Link",
"options": "Warehouse",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
@@ -145,8 +232,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "campaign",
"fieldtype": "Link",
"fieldname": "allow_delete",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -154,10 +241,39 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Campaign",
"label": "Allow Delete",
"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": "allow_user_to_edit_rate",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Allow user to edit Rate",
"length": 0,
"no_copy": 0,
"options": "Campaign",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -300,7 +416,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "currency",
"depends_on": "update_stock",
"fieldname": "warehouse",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -309,19 +426,19 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Currency",
"label": "Warehouse",
"length": 0,
"no_copy": 0,
"oldfieldname": "currency",
"oldfieldtype": "Select",
"options": "Currency",
"oldfieldname": "warehouse",
"oldfieldtype": "Link",
"options": "Warehouse",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@@ -332,8 +449,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "ignore_pricing_rule",
"fieldtype": "Check",
"fieldname": "campaign",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -341,69 +458,10 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Ignore Pricing Rule",
"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": "allow_delete",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Allow Delete",
"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": "allow_user_to_edit_rate",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Allow user to edit Rate",
"label": "Campaign",
"length": 0,
"no_copy": 0,
"options": "Campaign",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -422,6 +480,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "section_break_11",
"fieldtype": "Section Break",
"hidden": 0,
@@ -482,6 +541,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "section_break_14",
"fieldtype": "Section Break",
"hidden": 0,
@@ -602,6 +662,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "section_break_16",
"fieldtype": "Section Break",
"hidden": 0,
@@ -882,6 +943,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "offline_pos_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1037,6 +1099,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "section_break_19",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1046,6 +1109,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Accounting",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -1060,6 +1124,38 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "currency",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Currency",
"length": 0,
"no_copy": 0,
"oldfieldname": "currency",
"oldfieldtype": "Select",
"options": "Currency",
"permlevel": 0,
"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,
@@ -1154,38 +1250,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "taxes_and_charges",
"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": "Taxes and Charges",
"length": 0,
"no_copy": 0,
"oldfieldname": "charge",
"oldfieldtype": "Link",
"options": "Sales Taxes and Charges Template",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -1309,6 +1373,38 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "taxes_and_charges",
"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": "Taxes and Charges",
"length": 0,
"no_copy": 0,
"oldfieldname": "charge",
"oldfieldtype": "Link",
"options": "Sales Taxes and Charges Template",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"has_web_view": 0,
@@ -1322,7 +1418,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-09-01 15:55:14.890452",
"modified": "2017-10-27 06:45:32.957674",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Profile",

View File

@@ -19,7 +19,7 @@ class POSProfile(Document):
def check_for_duplicate(self):
res = frappe.db.sql("""select name, user from `tabPOS Profile`
where ifnull(user, '') = %s and name != %s and company = %s""",
where ifnull(user, '') = %s and name != %s and company = %s and ifnull(disabled, 0) != 1""",
(self.user, self.name, self.company))
if res:
if res[0][1]:

View File

@@ -41,6 +41,7 @@ def make_pos_profile():
"expense_account": "_Test Account Cost for Goods Sold - _TC",
"income_account": "Sales - _TC",
"name": "_Test POS Profile",
"pos_profile_name": "_Test POS Profile",
"naming_series": "_T-POS Profile-",
"selling_price_list": "_Test Price List",
"territory": "_Test Territory",

View File

@@ -12,8 +12,5 @@ class POSSettings(Document):
def set_link_for_pos(self):
link = 'pos' if self.use_pos_in_offline_mode else 'point-of-sale'
desktop_icon = frappe.db.get_value('Desktop Icon',
{'standard': 1, 'module_name': 'POS'}, 'name')
if desktop_icon:
frappe.db.set_value('Desktop Icon', desktop_icon, 'link', link)
frappe.db.sql(""" update `tabDesktop Icon` set link = '{0}'
where module_name like '%pos%'""".format(link))

View File

@@ -1,5 +1,6 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "hash",
@@ -10,20 +11,24 @@
"doctype": "DocType",
"document_type": "Setup",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Valuation and Total",
"default": "Total",
"fieldname": "category",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Consider Tax or Charge for",
"length": 0,
"no_copy": 0,
@@ -34,6 +39,7 @@
"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,
@@ -41,6 +47,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -52,7 +59,9 @@
"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 or Deduct",
"length": 0,
"no_copy": 0,
@@ -63,6 +72,7 @@
"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,
@@ -70,6 +80,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -80,7 +91,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Type",
"length": 0,
"no_copy": 0,
@@ -91,6 +104,7 @@
"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,
@@ -98,6 +112,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -109,7 +124,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Reference Row #",
"length": 0,
"no_copy": 0,
@@ -119,6 +136,7 @@
"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,
@@ -126,6 +144,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -137,7 +156,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Is this Tax included in Basic Rate?",
"length": 0,
"no_copy": 0,
@@ -146,6 +167,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 1,
"reqd": 0,
"search_index": 0,
@@ -153,6 +175,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -163,13 +186,16 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@@ -177,6 +203,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -187,7 +214,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Account Head",
"length": 0,
"no_copy": 0,
@@ -198,6 +227,7 @@
"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,
@@ -205,6 +235,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -216,7 +247,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Cost Center",
"length": 0,
"no_copy": 0,
@@ -227,6 +260,7 @@
"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,
@@ -234,17 +268,20 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "description",
"fieldtype": "Text Editor",
"fieldtype": "Small Text",
"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": "Description",
"length": 0,
"no_copy": 0,
@@ -255,6 +292,7 @@
"print_hide_if_no_value": 0,
"print_width": "300px",
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
@@ -263,6 +301,7 @@
"width": "300px"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -273,7 +312,9 @@
"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,
@@ -281,6 +322,7 @@
"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,
@@ -288,6 +330,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -298,7 +341,9 @@
"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,
@@ -308,6 +353,7 @@
"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,
@@ -315,6 +361,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -325,7 +372,9 @@
"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,
@@ -333,6 +382,7 @@
"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,
@@ -340,6 +390,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -350,7 +401,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Amount",
"length": 0,
"no_copy": 0,
@@ -361,6 +414,7 @@
"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,
@@ -368,6 +422,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -378,7 +433,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Tax Amount After Discount Amount",
"length": 0,
"no_copy": 0,
@@ -388,6 +445,7 @@
"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,
@@ -395,6 +453,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -405,7 +464,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Total",
"length": 0,
"no_copy": 0,
@@ -416,6 +477,7 @@
"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,
@@ -423,6 +485,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -433,7 +496,9 @@
"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,
@@ -441,6 +506,7 @@
"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,
@@ -448,6 +514,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -458,7 +525,9 @@
"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 (Company Currency)",
"length": 0,
"no_copy": 0,
@@ -468,6 +537,7 @@
"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,
@@ -475,6 +545,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -485,7 +556,9 @@
"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 (Company Currency)",
"length": 0,
"no_copy": 0,
@@ -495,6 +568,7 @@
"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,
@@ -502,6 +576,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -512,7 +587,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Tax Amount After Discount Amount",
"length": 0,
"no_copy": 0,
@@ -522,6 +599,7 @@
"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,
@@ -529,6 +607,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -539,7 +618,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Item Wise Tax Detail ",
"length": 0,
"no_copy": 0,
@@ -549,6 +630,7 @@
"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,
@@ -556,6 +638,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -565,8 +648,10 @@
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Parenttype",
"length": 0,
"no_copy": 0,
@@ -576,6 +661,7 @@
"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,
@@ -583,17 +669,17 @@
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 1,
"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": "2016-08-26 03:20:22.118330",
"modified": "2017-12-05 13:37:44.483509",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Taxes and Charges",
@@ -602,5 +688,7 @@
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"track_changes": 1,
"track_seen": 0
}

View File

@@ -92,6 +92,7 @@ def update_pos_profile_data(doc, pos_profile, company_data):
doc.customer_group = pos_profile.get('customer_group') or get_root('Customer Group')
doc.territory = pos_profile.get('territory') or get_root('Territory')
doc.terms = frappe.db.get_value('Terms and Conditions', pos_profile.get('tc_name'), 'terms') or doc.terms or ''
doc.offline_pos_name = ''
def get_root(table):
root = frappe.db.sql(""" select name from `tab%(table)s` having

View File

@@ -70,7 +70,6 @@ class SalesInvoice(SellingController):
self.clear_unallocated_advances("Sales Invoice Advance", "advances")
self.add_remarks()
self.validate_write_off_account()
self.validate_duplicate_offline_pos_entry()
self.validate_account_for_change_amount()
self.validate_fixed_asset()
self.set_income_account_for_fixed_assets()
@@ -248,7 +247,7 @@ class SalesInvoice(SellingController):
super(SalesInvoice, self).set_missing_values(for_validate)
if pos:
return {"print_format": pos.get("print_format") }
return {"print_format": pos.get("print_format_for_online") }
def update_time_sheet(self, sales_invoice):
for d in self.timesheets:
@@ -305,6 +304,7 @@ class SalesInvoice(SellingController):
self.account_for_change_amount = frappe.db.get_value('Company', self.company, 'default_cash_account')
if pos:
self.pos_profile = pos.name
if not for_validate and not self.customer:
self.customer = pos.customer
self.mode_of_payment = pos.mode_of_payment
@@ -463,12 +463,6 @@ class SalesInvoice(SellingController):
if flt(self.write_off_amount) and not self.write_off_account:
msgprint(_("Please enter Write Off Account"), raise_exception=1)
def validate_duplicate_offline_pos_entry(self):
if self.is_pos and self.offline_pos_name \
and frappe.db.get_value('Sales Invoice',
{'offline_pos_name': self.offline_pos_name, 'docstatus': 1}):
frappe.throw(_("Duplicate offline pos sales invoice {0}").format(self.offline_pos_name))
def validate_account_for_change_amount(self):
if flt(self.change_amount) and not self.account_for_change_amount:
msgprint(_("Please enter Account for Change Amount"), raise_exception=1)
@@ -676,28 +670,28 @@ class SalesInvoice(SellingController):
# income account gl entries
for item in self.get("items"):
if flt(item.base_net_amount):
account_currency = get_account_currency(item.income_account)
gl_entries.append(
self.get_gl_dict({
"account": item.income_account,
"against": self.customer,
"credit": item.base_net_amount,
"credit_in_account_currency": item.base_net_amount \
if account_currency==self.company_currency else item.net_amount,
"cost_center": item.cost_center
}, account_currency)
)
if item.is_fixed_asset:
asset = frappe.get_doc("Asset", item.asset)
fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset, item.base_net_amount)
fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset, is_sale=True)
for gle in fixed_asset_gl_entries:
gle["against"] = self.customer
gl_entries.append(self.get_gl_dict(gle))
asset.db_set("disposal_date", self.posting_date)
asset.set_status("Sold" if self.docstatus==1 else None)
else:
account_currency = get_account_currency(item.income_account)
gl_entries.append(
self.get_gl_dict({
"account": item.income_account,
"against": self.customer,
"credit": item.base_net_amount,
"credit_in_account_currency": item.base_net_amount \
if account_currency==self.company_currency else item.net_amount,
"cost_center": item.cost_center
}, account_currency)
)
# expense account gl entries
if cint(self.update_stock) and \

View File

@@ -179,41 +179,12 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
}
},
dialog_actions: function () {
var me = this;
$(this.list_body).find('.list-select-all').click(function () {
me.removed_items = [];
$(me.list_body).find('.list-delete').prop("checked", $(this).is(":checked"))
if ($(this).is(":checked")) {
$.each(me.si_docs, function (index, data) {
for (key in data) {
me.removed_items.push(key)
}
})
}
me.toggle_delete_button();
})
$(this.list_body).find('.list-delete').click(function () {
me.name = $(this).parent().parent().attr('invoice-name');
if ($(this).is(":checked")) {
me.removed_items.push(me.name);
} else {
me.removed_items.pop(me.name)
}
me.toggle_delete_button();
})
},
edit_record: function () {
var me = this;
doc_data = this.get_invoice_doc(this.si_docs);
if (doc_data) {
this.frm.doc = doc_data[0][this.name];
this.frm.doc = doc_data[0][this.frm.doc.offline_pos_name];
this.set_missing_values();
this.refresh(false);
this.toggle_input_field();
@@ -226,16 +197,15 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
this.validate_list()
this.remove_doc_from_localstorage()
this.update_localstorage();
// this.dialog_actions();
this.toggle_delete_button();
},
validate_list: function() {
var me = this;
this.si_docs = this.get_submitted_invoice()
$.each(this.removed_items, function(index, name){
$.each(this.removed_items, function(index, pos_name){
$.each(me.si_docs, function(key, data){
if(me.si_docs[key][name] && me.si_docs[key][name].offline_pos_name == name ){
if(me.si_docs[key][pos_name] && me.si_docs[key][pos_name].offline_pos_name == pos_name ){
frappe.throw(__("Submitted orders can not be deleted"))
}
})
@@ -294,7 +264,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
return $.grep(this.si_docs, function (data) {
for (key in data) {
return key == me.name
return key == me.frm.doc.offline_pos_name;
}
})
},
@@ -348,7 +318,6 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
create_new: function () {
var me = this;
this.frm = {}
this.name = null;
this.load_data(true);
this.setup();
this.set_default_customer()
@@ -362,6 +331,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
if (load_doc) {
this.frm.doc = JSON.parse(localStorage.getItem('doc'));
this.frm.doc.offline_pos_name = null;
}
$.each(this.meta, function (i, data) {
@@ -629,6 +599,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
// this.list_customers.empty();
this.si_docs = this.get_doc_from_localstorage();
if (!this.si_docs.length) {
this.list_customers.find('.list-customers-table').html("");
return;
}
@@ -655,7 +626,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
me.list_customers_btn.toggleClass("view_customer");
me.pos_bill.show();
me.list_customers_btn.show();
me.name = $(this).parents().attr('invoice-name')
me.frm.doc.offline_pos_name = $(this).parents().attr('invoice-name')
me.edit_record();
})
@@ -675,11 +646,11 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
});
$(this.wrapper).find('.list-delete').click(function () {
me.name = $(this).parent().parent().attr('invoice-name');
me.frm.doc.offline_pos_name = $(this).parent().parent().attr('invoice-name');
if ($(this).is(":checked")) {
me.removed_items.push(me.name);
me.removed_items.push(me.frm.doc.offline_pos_name);
} else {
me.removed_items.pop(me.name)
me.removed_items.pop(me.frm.doc.offline_pos_name)
}
me.toggle_delete_button();
@@ -1435,7 +1406,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
},
update_paid_amount_status: function (update_paid_amount) {
if (this.name) {
if (this.frm.doc.offline_pos_name) {
update_paid_amount = update_paid_amount ? false : true;
}
@@ -1643,18 +1614,17 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
create_invoice: function () {
var me = this;
var invoice_data = {}
var invoice_data = {};
this.si_docs = this.get_doc_from_localstorage();
if (this.name) {
this.update_invoice()
if (this.frm.doc.offline_pos_name) {
this.update_invoice();
} else {
this.name = $.now();
this.frm.doc.offline_pos_name = this.name;
this.frm.doc.offline_pos_name = $.now();
this.frm.doc.posting_date = frappe.datetime.get_today();
this.frm.doc.posting_time = frappe.datetime.now_time();
this.frm.doc.pos_profile = this.pos_profile_data['name'];
invoice_data[this.name] = this.frm.doc
this.si_docs.push(invoice_data)
invoice_data[this.frm.doc.offline_pos_name] = this.frm.doc;
this.si_docs.push(invoice_data);
this.update_localstorage();
this.set_primary_action();
}
@@ -1666,12 +1636,12 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
this.si_docs = this.get_doc_from_localstorage();
$.each(this.si_docs, function (index, data) {
for (var key in data) {
if (key == me.name) {
if (key == me.frm.doc.offline_pos_name) {
me.si_docs[index][key] = me.frm.doc;
me.update_localstorage();
}
}
})
});
},
update_localstorage: function () {
@@ -1710,6 +1680,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
freeze_screen = this.freeze_screen || false;
if ((this.si_docs.length || this.email_queue_list || this.customers_list) && !this.freeze) {
this.freeze = true;
frappe.call({
method: "erpnext.accounts.doctype.sales_invoice.pos.make_invoice",
freeze: freeze_screen,
@@ -1720,17 +1692,19 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
},
callback: function (r) {
if (r.message) {
me.freeze = false;
me.customers = r.message.synced_customers_list;
me.address = r.message.synced_address;
me.contacts = r.message.synced_contacts;
me.removed_items = r.message.invoice;
me.removed_email = r.message.email_queue
me.removed_customers = r.message.customers
me.removed_email = r.message.email_queue;
me.removed_customers = r.message.customers;
me.remove_doc_from_localstorage();
me.remove_email_queue_from_localstorage();
me.remove_customer_from_localstorage();
me.prepare_customer_mapper()
me.autocomplete_customers()
me.prepare_customer_mapper();
me.autocomplete_customers();
me.render_list_customers();
}
}
})

View File

@@ -6,6 +6,7 @@ QUnit.test("test:Sales Invoice", function(assert) {
() => {
return frappe.tests.make("POS Profile", [
{naming_series: "SINV"},
{pos_profile_name: "_Test POS Profile"},
{country: "India"},
{currency: "INR"},
{write_off_account: "Write Off - FT"},

View File

@@ -176,29 +176,31 @@ def get_party_account(party_type, party, company):
if not company:
frappe.throw(_("Please select a Company"))
if party:
if not party:
return
account = frappe.db.get_value("Party Account",
{"parenttype": party_type, "parent": party, "company": company}, "account")
if not account and party_type in ['Customer', 'Supplier']:
party_group_doctype = "Customer Group" if party_type=="Customer" else "Supplier Type"
group = frappe.db.get_value(party_type, party, scrub(party_group_doctype))
account = frappe.db.get_value("Party Account",
{"parenttype": party_type, "parent": party, "company": company}, "account")
{"parenttype": party_group_doctype, "parent": group, "company": company}, "account")
if not account and party_type in ['Customer', 'Supplier']:
party_group_doctype = "Customer Group" if party_type=="Customer" else "Supplier Type"
group = frappe.db.get_value(party_type, party, scrub(party_group_doctype))
account = frappe.db.get_value("Party Account",
{"parenttype": party_group_doctype, "parent": group, "company": company}, "account")
if not account and party_type in ['Customer', 'Supplier']:
default_account_name = "default_receivable_account" \
if party_type=="Customer" else "default_payable_account"
account = frappe.db.get_value("Company", company, default_account_name)
if not account and party_type in ['Customer', 'Supplier']:
default_account_name = "default_receivable_account" \
if party_type=="Customer" else "default_payable_account"
account = frappe.db.get_value("Company", company, default_account_name)
existing_gle_currency = get_party_gle_currency(party_type, party, company)
if existing_gle_currency:
if account:
account_currency = frappe.db.get_value("Account", account, "account_currency")
if (account and account_currency != existing_gle_currency) or not account:
account = get_party_gle_account(party_type, party, company)
existing_gle_currency = get_party_gle_currency(party_type, party, company)
if existing_gle_currency:
if account:
account_currency = frappe.db.get_value("Account", account, "account_currency")
if (account and account_currency != existing_gle_currency) or not account:
account = get_party_gle_account(party_type, party, company)
return account
return account
def get_party_account_currency(party_type, party, company):
def generator():

View File

@@ -36,8 +36,14 @@
<br>{%= data[i][__("Voucher No")] %}</td>
<td>
{% if(!(filters.customer || filters.supplier)) { %}
{%= data[i][__("Customer Name")] || data[i][__("Customer")] || data[i][__("Supplier Name")] || data[i][__("Supplier")] %}<br>{%= __("Remarks") %}:
{%= data[i][__("Customer")] || data[i][__("Supplier")] %}
{% if(data[i][__("Customer Name")] && data[i][__("Customer Name")] != data[i][__("Customer")]) { %}
<br> {%= data[i][__("Customer Name")] %}
{% } else if(data[i][__("Supplier Name")] != data[i][__("Supplier")]) { %}
<br> {%= data[i][__("Supplier Name")] %}
{% } %}
{% } %}
<br>{%= __("Remarks") %}:
{%= data[i][__("Remarks")] %}
</td>
<td style="text-align: right">
@@ -66,8 +72,13 @@
<td>
{% if(!(filters.customer || filters.supplier)) { %}
{%= data[i][__("Customer")] || data[i][__("Supplier")] %}
<br>{%= __("Remarks") %}:
{% if(data[i][__("Customer Name")] && data[i][__("Customer Name")] != data[i][__("Customer")]) { %}
<br> {%= data[i][__("Customer Name")] %}
{% } else if(data[i][__("Supplier Name")] != data[i][__("Supplier")]) { %}
<br> {%= data[i][__("Supplier Name")] %}
{% } %}
{% } %}
<br>{%= __("Remarks") %}:
{%= data[i][__("Remarks")] %}
</td>
{% } else { %}

View File

@@ -86,17 +86,20 @@ def get_accumulated_depreciations(assets, filters):
for d in assets:
asset = frappe.get_doc("Asset", d.name)
asset_depreciations.setdefault(d.asset_category, frappe._dict({
"accumulated_depreciation_as_on_from_date": asset.opening_accumulated_depreciation,
"depreciation_amount_during_the_period": 0,
"depreciation_eliminated_during_the_period": 0
}))
if d.asset_category in asset_depreciations:
asset_depreciations[d.asset_category]['accumulated_depreciation_as_on_from_date'] += asset.opening_accumulated_depreciation
else:
asset_depreciations.setdefault(d.asset_category, frappe._dict({
"accumulated_depreciation_as_on_from_date": asset.opening_accumulated_depreciation,
"depreciation_amount_during_the_period": 0,
"depreciation_eliminated_during_the_period": 0
}))
depr = asset_depreciations[d.asset_category]
for schedule in asset.get("schedules"):
if getdate(schedule.schedule_date) < getdate(filters.from_date):
if not asset.disposal_date and getdate(asset.disposal_date) >= getdate(filters.from_date):
if not asset.disposal_date or getdate(asset.disposal_date) >= getdate(filters.from_date):
depr.accumulated_depreciation_as_on_from_date += flt(schedule.depreciation_amount)
elif getdate(schedule.schedule_date) <= getdate(filters.to_date):
depr.depreciation_amount_during_the_period += flt(schedule.depreciation_amount)

View File

@@ -83,7 +83,7 @@ frappe.query_reports["General Ledger"] = {
return;
}
var fieldname = party_type.toLowerCase() + "_name";
var fieldname = frappe.scrub(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]);
});

View File

@@ -0,0 +1,40 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
frappe.query_reports["Sales Payment Summary"] = {
"filters": [
{
"fieldname":"from_date",
"label": __("From Date"),
"fieldtype": "Date",
"default": frappe.datetime.get_today(),
"reqd": 1,
"width": "80"
},
{
"fieldname":"to_date",
"label": __("To Date"),
"fieldtype": "Date",
"reqd": 1,
"default": frappe.datetime.get_today()
},
{
"fieldname":"company",
"label": __("Company"),
"fieldtype": "Link",
"options": "Company",
"default": frappe.defaults.get_user_default("Company")
},
{
"fieldname":"owner",
"label": __("Owner"),
"fieldtype": "Link",
"options": "User",
"defaults": user
},
{
"fieldname":"is_pos",
"label": __("POS?"),
"fieldtype": "Check"
}
]
};

View File

@@ -0,0 +1,26 @@
{
"add_total_row": 1,
"apply_user_permissions": 1,
"creation": "2017-11-03 16:31:45.757516",
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"modified": "2017-11-04 05:15:35.892659",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Payment Summary",
"owner": "Administrator",
"ref_doctype": "Sales Invoice",
"report_name": "Sales Payment Summary",
"report_type": "Script Report",
"roles": [
{
"role": "Accounts Manager"
},
{
"role": "Accounts User"
}
]
}

View File

@@ -0,0 +1,89 @@
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import cstr
def execute(filters=None):
columns, data = [], []
columns=get_columns()
data=get_sales_payment_data(filters, columns)
return columns, data
def get_columns():
return [
_("Date") + ":Date:80",
_("Owner") + "::150",
_("Payment Mode") + "::140",
_("Sales and Returns") + ":Currency/currency:120",
_("Taxes") + ":Currency/currency:120",
_("Payments") + ":Currency/currency:120",
_("Outstanding Amount") + ":Currency/currency:150",
]
def get_sales_payment_data(filters, columns):
sales_invoice_data = get_sales_invoice_data(filters)
data = []
mode_of_payments = get_mode_of_payments(filters)
for inv in sales_invoice_data:
mode_of_payment = inv["owner"]+cstr(inv["posting_date"])
row = [inv.posting_date, inv.owner,", ".join(mode_of_payments.get(mode_of_payment, [])),
inv.net_total,
inv.total_taxes, (inv.net_total + inv.total_taxes - inv.outstanding_amount),
inv.outstanding_amount]
data.append(row)
return data
def get_conditions(filters):
conditions = ""
if filters.get("from_date"): conditions += "a.posting_date >= %(from_date)s"
if filters.get("to_date"): conditions += " and a.posting_date <= %(to_date)s"
if filters.get("company"): conditions += " and a.company=%(company)s"
if filters.get("customer"): conditions += " and a.customer = %(customer)s"
if filters.get("owner"): conditions += " and a.owner = %(owner)s"
if filters.get("is_pos"): conditions += " and a.is_pos = %(is_pos)s"
return conditions
def get_sales_invoice_data(filters):
conditions = get_conditions(filters)
return frappe.db.sql("""
select
a.posting_date, a.owner,
sum(a.net_total) as "net_total",
sum(a.total_taxes_and_charges) as "total_taxes",
sum(a.base_paid_amount) as "paid_amount",
sum(a.outstanding_amount) as "outstanding_amount"
from `tabSales Invoice` a
where a.docstatus = 1
and {conditions}
group by
a.owner, a.posting_date
""".format(conditions=conditions), filters, as_dict=1)
def get_mode_of_payments(filters):
mode_of_payments = {}
invoice_list = get_invoices(filters)
invoice_list_names = ",".join(['"' + invoice['name'] + '"' for invoice in invoice_list])
if invoice_list:
inv_mop = frappe.db.sql("""select a.owner,a.posting_date,b.mode_of_payment
from `tabSales Invoice` a, `tabSales Invoice Payment` b
where a.name = b.parent
and a.name in ({invoice_list_names})
union
select a.owner,a.posting_date,b.mode_of_payment
from `tabSales Invoice` a, `tabPayment Entry` b,`tabPayment Entry Reference` c
where a.name = c.reference_name
and b.name = c.parent
and a.name in ({invoice_list_names})
""".format(invoice_list_names=invoice_list_names), as_dict=1)
for d in inv_mop:
mode_of_payments.setdefault(d["owner"]+cstr(d["posting_date"]), []).append(d.mode_of_payment)
return mode_of_payments
def get_invoices(filters):
conditions = get_conditions(filters)
return frappe.db.sql("""select a.name
from `tabSales Invoice` a
where a.docstatus = 1 and {conditions}""".format(conditions=conditions),
filters, as_dict=1)

View File

@@ -134,8 +134,12 @@ def calculate_values(accounts, gl_entries_by_account, opening_balances, filters,
"account": "'" + _("Total") + "'",
"account_name": "'" + _("Total") + "'",
"warn_if_negative": True,
"opening_debit": 0.0,
"opening_credit": 0.0,
"debit": 0.0,
"credit": 0.0,
"closing_debit": 0.0,
"closing_credit": 0.0,
"parent_account": None,
"indent": 0,
"has_value": True,
@@ -156,7 +160,10 @@ def calculate_values(accounts, gl_entries_by_account, opening_balances, filters,
total_row["debit"] += d["debit"]
total_row["credit"] += d["credit"]
total_row["opening_debit"] += d["opening_debit"]
total_row["opening_credit"] += d["opening_credit"]
total_row["closing_debit"] += (d["opening_debit"] + d["debit"])
total_row["closing_credit"] += (d["opening_credit"] + d["credit"])
return total_row

View File

@@ -593,7 +593,9 @@ def get_outstanding_invoices(party_type, party, account, condition=None):
select ifnull(sum({payment_dr_or_cr}), 0)
from `tabGL Entry` payment_gl_entry
where payment_gl_entry.against_voucher_type = invoice_gl_entry.voucher_type
and payment_gl_entry.against_voucher = invoice_gl_entry.voucher_no
and if(invoice_gl_entry.voucher_type='Journal Entry',
payment_gl_entry.against_voucher = invoice_gl_entry.voucher_no,
payment_gl_entry.against_voucher = invoice_gl_entry.against_voucher)
and payment_gl_entry.party_type = invoice_gl_entry.party_type
and payment_gl_entry.party = invoice_gl_entry.party
and payment_gl_entry.account = invoice_gl_entry.account

View File

@@ -51,6 +51,7 @@ class PurchaseOrder(BuyingController):
self.validate_with_previous_doc()
self.validate_for_subcontracting()
self.validate_minimum_order_qty()
self.validate_bom_for_subcontracting_items()
self.create_raw_materials_supplied("supplied_items")
self.set_received_qty_for_drop_ship_items()
@@ -95,6 +96,13 @@ class PurchaseOrder(BuyingController):
frappe.throw(_("Item {0}: Ordered qty {1} cannot be less than minimum order qty {2} (defined in Item).").format(item_code,
qty, itemwise_min_order_qty.get(item_code)))
def validate_bom_for_subcontracting_items(self):
if self.is_subcontracted == "Yes":
for item in self.items:
if not item.bom:
frappe.throw(_("BOM is not specified for subcontracting item {0} at row {1}"\
.format(item.item_code, item.idx)))
def get_schedule_dates(self):
for d in self.get('items'):
if d.material_request_item and not d.schedule_date:

View File

@@ -468,6 +468,12 @@ def get_data():
"name": "Customer Credit Balance",
"doctype": "Customer"
},
{
"type": "report",
"is_query_report": True,
"name": "Sales Payment Summary",
"doctype": "Sales Invoice"
}
]
},
{

View File

@@ -209,10 +209,10 @@ class AccountsController(TransactionBase):
tax_master_doctype = self.meta.get_field("taxes_and_charges").options
if not self.get("taxes"):
if self.is_new() and not self.get("taxes"):
if not self.get("taxes_and_charges"):
# get the default tax master
self.set("taxes_and_charges", frappe.db.get_value(tax_master_doctype, {"is_default": 1}))
self.taxes_and_charges = frappe.db.get_value(tax_master_doctype, {"is_default": 1})
self.append_taxes_from_master(tax_master_doctype)
@@ -608,7 +608,10 @@ def get_tax_rate(account_head):
@frappe.whitelist()
def get_default_taxes_and_charges(master_doctype):
default_tax = frappe.db.get_value(master_doctype, {"is_default": 1})
return get_taxes_and_charges(master_doctype, default_tax)
return {
'taxes_and_charges': default_tax,
'taxes': get_taxes_and_charges(master_doctype, default_tax)
}
@frappe.whitelist()
def get_taxes_and_charges(master_doctype, master_name):

View File

@@ -171,7 +171,7 @@ class BuyingController(StockController):
for item in self.get("items"):
if self.doctype in ["Purchase Receipt", "Purchase Invoice"]:
item.rm_supp_cost = 0.0
if item.item_code in self.sub_contracted_items:
if item.bom and item.item_code in self.sub_contracted_items:
self.update_raw_materials_supplied(item, raw_material_table)
if [item.item_code, item.name] not in parent_items:

View File

@@ -56,7 +56,7 @@ def validate_item_variant_attributes(item, args=None):
if not args:
args = {d.attribute.lower():d.attribute_value for d in item.attributes}
attribute_values, numeric_values = get_attribute_values()
attribute_values, numeric_values = get_attribute_values(item)
for attribute, value in args.items():
if not value:
@@ -96,16 +96,17 @@ def validate_item_attribute_value(attributes_list, attribute, attribute_value, i
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'))
def get_attribute_values():
def get_attribute_values(item):
if not frappe.flags.attribute_values:
attribute_values = {}
numeric_values = {}
for t in frappe.get_all("Item Attribute Value", fields=["parent", "attribute_value"]):
attribute_values.setdefault(t.parent.lower(), []).append(t.attribute_value)
for t in frappe.get_all('Item Attribute',
fields=["name", "from_range", "to_range", "increment"], filters={'numeric_values': 1}):
numeric_values[t.name.lower()] = t
for t in frappe.get_all('Item Variant Attribute',
fields=["attribute", "from_range", "to_range", "increment"],
filters={'numeric_values': 1, 'parent': item.variant_of}):
numeric_values[t.attribute.lower()] = t
frappe.flags.attribute_values = attribute_values
frappe.flags.numeric_values = numeric_values

View File

@@ -204,8 +204,8 @@ def bom(doctype, txt, searchfield, start, page_len, filters):
{
'txt': "%%%s%%" % frappe.db.escape(txt),
'_txt': txt.replace("%", ""),
'start': start,
'page_len': page_len
'start': start or 0,
'page_len': page_len or 20
})
def get_project_name(doctype, txt, searchfield, start, page_len, filters):

View File

@@ -399,7 +399,8 @@ class calculate_taxes_and_totals(object):
for tax in self.doc.get("taxes"):
if tax.charge_type == "Actual":
actual_taxes_dict.setdefault(tax.idx, tax.tax_amount)
tax_amount = self.get_tax_amount_if_for_valuation_or_deduction(tax.tax_amount, tax)
actual_taxes_dict.setdefault(tax.idx, tax_amount)
elif tax.row_id in actual_taxes_dict:
actual_tax_amount = flt(actual_taxes_dict.get(tax.row_id, 0)) * flt(tax.rate) / 100
actual_taxes_dict.setdefault(tax.idx, actual_tax_amount)

View File

@@ -48,16 +48,16 @@ class Opportunity(TransactionBase):
# check if customer is already created agains the self.contact_email
customer = frappe.db.sql("""select
distinct `tabDynamic Link`.link_name as customer
from
from
`tabContact`,
`tabDynamic Link`
where `tabContact`.email_id='{0}'
and
and
`tabContact`.name=`tabDynamic Link`.parent
and
ifnull(`tabDynamic Link`.link_name, '')<>''
and
`tabDynamic Link`.link_doctype='Customer'
ifnull(`tabDynamic Link`.link_name, '')<>''
and
`tabDynamic Link`.link_doctype='Customer'
""".format(self.contact_email), as_dict=True)
if customer and customer[0].customer:
self.customer = customer[0].customer
@@ -118,9 +118,9 @@ class Opportunity(TransactionBase):
def has_ordered_quotation(self):
return frappe.db.sql("""
select q.name
select q.name
from `tabQuotation` q, `tabQuotation Item` qi
where q.name = qi.parent and q.docstatus=1 and qi.prevdoc_docname =%s
where q.name = qi.parent and q.docstatus=1 and qi.prevdoc_docname =%s
and q.status = 'Ordered'""", self.name)
def has_lost_quotation(self):
@@ -233,8 +233,8 @@ def make_quotation(source_name, target_doc=None):
# get default taxes
taxes = get_default_taxes_and_charges("Sales Taxes and Charges Template")
if taxes:
quotation.extend("taxes", taxes)
if taxes.get('taxes'):
quotation.update(taxes)
quotation.run_method("set_missing_values")
quotation.run_method("calculate_taxes_and_totals")

View File

@@ -5,6 +5,7 @@ def get_data():
'fieldname': 'prevdoc_docname',
'non_standard_fieldnames': {
'Supplier Quotation': 'opportunity',
'Quotation': 'opportunity'
},
'transactions': [
{

View File

@@ -348,8 +348,10 @@ def setup_budget():
budget.action_if_annual_budget_exceeded = "Warn"
expense_ledger_count = frappe.db.count("Account", {"is_group": "0", "root_type": "Expense"})
add_random_children(budget, "accounts", rows=random.randint(10, expense_ledger_count), randomize = { "account": ("Account", {"is_group": "0", "root_type": "Expense"})
}, unique="account")
add_random_children(budget, "accounts", rows=random.randint(10, expense_ledger_count),
randomize = {
"account": ("Account", {"is_group": "0", "root_type": "Expense"})
}, unique="account")
for d in budget.accounts:
d.budget_amount = random.randint(5, 100) * 10000
@@ -361,6 +363,7 @@ def setup_pos_profile():
company_abbr = frappe.db.get_value("Company", erpnext.get_default_company(), "abbr")
pos = frappe.new_doc('POS Profile')
pos.user = frappe.db.get_global('demo_accounts_user')
pos.pos_profile_name = "Demo POS Profile"
pos.naming_series = 'SINV-'
pos.update_stock = 0
pos.write_off_account = 'Cost of Goods Sold - '+ company_abbr

View File

@@ -1,3 +1,4 @@
introduction
accounts
projects
schools

View File

@@ -0,0 +1,6 @@
# Costo de Actividad
El costo de la actividad registra la tasa de facturación por hora y la tasa de costos de un empleado en comparación con un tipo de actividad.
El sistema hace uso de esta tasa mientras hace registros de tiempo. Se usa para Costeo de proyectos.
<img class="screenshot" alt="Activity Cost" src="/docs/assets/img/project/activity_cost.png">

View File

@@ -0,0 +1,15 @@
# Tipo de Actividad
Los tipos de actividad son la lista de los diferentes tipos de actividades sobre las que se hacen registro de tiempo.
<img class="screenshot" alt="Activity Type" src="/docs/assets/img/project/activity_type.png">
Por defecto, los siguientes tipos de actividades son creados.
* Planning
* Research
* Proposal Writing
* Execution
* Communication
{next}

View File

@@ -0,0 +1,3 @@
# Artículos
{index}

View File

@@ -0,0 +1 @@
project-costing

View File

@@ -0,0 +1,40 @@
# Costeo de proyectos
Cada proyecto tiene multiples tareas asociadas a el. Para hacer el seguimiento del costo actual de un proyecto, primeramente en términos de servicios, el usuario
tiene que crear un registro de tiempo basado en el tiempo que invirtió en una tarea del proyecto. Siguiendo los pasos de como puedes hacer el seguimiento del costo actual de un servicio usando el proyecto.
#### Tipo de actividad
Tipo de actividad es un maestro de los servicios ofrecidos por su personal. Puedes agregar un nuevo Tipo de Actividad desde:
`Project > Activity Type > New`
#### Costo de actividad
Costo de actividad es un maestro donde puedes hacer el seguimiento de los montos de facturación y costo de cada empleado, y por cada tipo de Tipo de Actividad.
<img alt="Activity Cost" class="screenshot" src="/docs/assets/img/articles/Screen Shot 2015-06-11 at 4.57.01 pm.png">
#### Registro de Tiempo
Basados en el tiempo actual invertido en una Tarea del Proyecto, El empleado va a crear un registro de tiempo.
<img alt="Time Log" class="screenshot" src="/docs/assets/img/articles/Screen Shot 2015-06-11 at 4.59.49 pm.png">
Al momento de seleccionar el Tipo de Actividad en el Registro de tiempo, el monto de Facturación y Costo del empleado va a ser traído de su respectivo registro en el master de Costo de Actividad.
<img alt="Time Log Costing" class="screenshot" src="/docs/assets/img/articles/Screen Shot 2015-06-11 at 5.00.06 pm.png">
Multiplicando esos montos con el total de número de horas en el registro de tiempo, nos da el monto de costos y Facturación para el registro de tiempo específico.
#### Costeo en Proyectos y Tareas
Basados en el total de registros de tiempos creados por una tarea en específico, su costo va a ser actualizado en el registro maestro de la tarea, o sea, en el detalle de la tarea.
<img alt="Costing in Task" class="screenshot" src="/docs/assets/img/articles/Screen Shot 2015-06-11 at 5.02.54 pm.png">
De la misma manera, el detalle del Proyecto va a actualizar su costo basado en el total de registros de tiempo a ese proyecto, y las tareas asociadas a ese proyecto.
<img alt="Costing in Project" class="screenshot" src="/docs/assets/img/articles/Screen Shot 2015-06-11 at 5.02.29 pm.png">
<!-- markdown -->

View File

@@ -0,0 +1,15 @@
# Proyectos
ERPNext le ayuda en la administración de su proyecto a traves de la creacion de tareas y
poder asignarlas a diferentes personas.
Las compras y las ventas también se pueden rastrear en relación con los proyectos y
esto puede ayudar a la empresa a controlar su presupuesto, entrega y rentabilidad para un proyecto.
Los proyectos pueden ser usados para manejar los proyectos internos, trabajos de manufacturación y
planificación de servicios. Para los trabajos de servicios, los Time Sheets (hojas de tiempo) pueden ser creadas
para facturar a los clientes, en caso que el proceso de facturación se haga basado en tiempo y dinero de tareas.
### Temas
{index}

View File

@@ -0,0 +1,7 @@
tasks
project
time-log-batch
activity-type
activity-cost
articles
timesheet

View File

@@ -0,0 +1,110 @@
# Proyecto
El manejo de proyectos en ERPNext se hace a traves de tareas. Puedes crear un proyecto y asignar varias tareas al mismo.
<img class="screenshot" alt="Project" src="/docs/assets/img/project/project.png">
También puedes hacer el seguimiento del % completado del proyecto usando diferentes métodos.
1. Tareas Completadas
2. Progreso de tareas
3. Peso de tarea
<img class="screenshot" alt="Project" src="/docs/assets/img/project/project-percent-complete.png">
Algunos ejemplos de como el % completado es cálculado basado en tareas.
<img class="screenshot" alt="Project" src="/docs/assets/img/project/percent-complete-calc.png">
<img class="screenshot" alt="Project" src="/docs/assets/img/project/percent-complete-formula.png">
### Manejando tareas
Los proyecto pueden ser divididos en multiples tareas.
Las tareas pueden ser creadas a traves del documento de Proyecto o pueden ser creadas via [Tarea](/docs/user/manual/en/projects/tasks.html)
<img class="screenshot" alt="Project" src="/docs/assets/img/project/project_task.png">
* Para ver las tareas creadas a un proyecto click en 'Tasks'
<img class="screenshot" alt="Project - View Task" src="/docs/assets/img/project/project_view_task.png">
<img class="screenshot" alt="Project - Task List" src="/docs/assets/img/project/project_task_list.png">
* También puedes ver las tareas desde la misma vista del proyecto.
<img class="screenshot" alt="Project - Task Grid" src="/docs/assets/img/project/project_task_grid.png">
* Para agregar peso a las tareas puedes seguir los pasos siguientes
<img class="screenshot" alt="Project - Task Grid" src="/docs/assets/img/project/tasks.png">
<img class="screenshot" alt="Project - Task Grid" src="/docs/assets/img/project/task-weights.png">
### Manejando tiempo
ERPNext usa [Time Log](/docs/user/manual/en/projects/time-log.html) para hacer el seguimiento del progreso de un Proyecto.
Puedes crear registros de tiempo sobre cada Tarea.
El tiempo actual de inicio y finalización junto con el costo deben ser actualizados basados en los Registros de Tiempo.
* Para ver los Registros de Tiempo realizados a un proyecto, dar click en 'Time Logs'
<img class="screenshot" alt="Project - View Time Log" src="/docs/assets/img/project/project_view_time_log.png">
<img class="screenshot" alt="Project - Time Log List" src="/docs/assets/img/project/project_time_log_list.png">
* Puedes agregar un registro de tiempo directamente y luego asociarlo con el proyecto.
<img class="screenshot" alt="Project - Link Time Log" src="/docs/assets/img/project/project_time_log_link.png">
### Gestión de gastos
Puede reservar la [Reclamación de gastos](/docs/user/manual/en/human-resources/expense-claim.html) contra una tarea de proyecto.
El sistema actualizará el monto total de las reclamaciones de gastos en la sección de costos del proyecto.
* Para ver las reclamaciones de gastos realizadas en un proyecto, haga clic en 'Reclamaciones de gastos'
<img class="screenshot" alt="Project - View Expense Claim" src="/docs/assets/img/project/project_view_expense_claim.png">
* También puede crear un Reclamo de gastos directamente y vincularlo al Proyecto.
<img class="screenshot" alt="Project - Link Expense Claim" src="/docs/assets/img/project/project_expense_claim_link.png">
* El monto total de los Reclamos de gastos reservados contra un proyecto se muestra en 'Reclamo de gastos totales' en la Sección de Costos del proyecto
<img class="screenshot" alt="Project - Total Expense Claim" src="/docs/assets/img/project/project_total_expense_claim.png">
### Centro de Costo
Puedes crear un [Cost Center](/docs/user/manual/en/accounts/setup/cost-center.html) sobre un proyecto o usar un centro de costo existente para hacer el seguimiento de todos los gastos realizados al proyecto.
<img class="screenshot" alt="Project - Cost Center" src="/docs/assets/img/project/project_cost_center.png">
###Costeo del proyecto
La sección Costeo del proyecto le ayuda a rastrear el tiempo y los gastos incurridos en relación con el proyecto.
<img class="screenshot" alt="Project - Costing" src="/docs/assets/img/project/project_costing.png">
* La sección de cálculo de costos se actualiza según los registros de tiempo realizados.
* El margen bruto es la diferencia entre el monto total de costos y el monto total de facturación
###Facturación
Puedes crear/enlazar una [Sales Order](/docs/user/manual/en/selling/sales-order.html) a un proyecto. Una vez asociada puedes usar el módulo de ventas para facturar a un cliente sobre el proyecto.
<img class="screenshot" alt="Project - Sales Order" src="/docs/assets/img/project/project_sales_order.png">
###Gantt Chart
Un Gantt Chart muestra la planificación del proyecto.
ERPNext te provee con una vista para visualizar las tareas de forma calendarizada usando un Gantt Chart (Hoja de Gantt).
* Para visualizar el gantt chart de un proyecto, ve hasta el proyecto y dar click en 'Gantt Chart'
<img class="screenshot" alt="Project - View Gantt Chart" src="/docs/assets/img/project/project_view_gantt_chart.png">
<img class="screenshot" alt="Project - Gantt Chart" src="/docs/assets/img/project/project_gantt_chart.png">
{next}

View File

@@ -0,0 +1,61 @@
# Tareas
Proyecto es dividido en Tareas.
En ERPNext, puedes crear las tareas de forma independiente.
<img class="screenshot" alt="Task" src="/docs/assets/img/project/task.png">
### Estado de una Tarea
Una tarea puede tener uno de los siguientes estados - Abierto, Trabajando, Pendiente de Revisión, Cerrado, o Cancelado.
<img class="screenshot" alt="Task - Status" src="/docs/assets/img/project/task_status.png">
* Por defecto, cada nueva tarea creada se le establece el estado 'Abierto'.
* Si un registro de tiempo es realizado sobre una tarea, su estado es asignado a 'Working'.
### Tarea Dependiente
Puedes especificar una lista de tareas dependientes en la sección 'Depende de'
<img class="screenshot" alt="Depends On" src="/docs/assets/img/project/task_depends_on.png">
* No puedes cerrar una tarea padre hasta que todas las tareas dependientes esten cerradas.
* Si una tarea dependiente se encuentra en retraso y se sobrepone con la fecha esperada de inicio de la tarea padre, el sistema va a re calandarizar la tarea padre.
### Manejando el tiempo
ERPNext usa [Time Log](/docs/user/manual/en/projects/time-log.html) para seguir el progreso de una tarea.
Puedes crear varios registros de tiempo para cada tarea.
El tiempo de inicio y fin actual junto con el costo es actualizado en base al Registro de Tiempo.
* Para ver el Registro de tiempo realizado a una tarea, dar click en 'Time Logs'
<img class="screenshot" alt="Task - View Time Log" src="/docs/assets/img/project/task_view_time_log.png">
<img class="screenshot" alt="Task - Time Log List" src="/docs/assets/img/project/task_time_log_list.png">
* Puedes también crear un Registro de Tiempo directamente y luego asociarlo a una Tarea.
<img class="screenshot" alt="Task - Link Time Log" src="/docs/assets/img/project/task_time_log_link.png">
### Gestión de gastos
Puede reservar la [Reclamación de gastos](/docs/user/manual/en/human-resources/expense-claim.html) contra una tarea de proyecto.
El sistema actualizará el monto total de las reclamaciones de gastos en la sección de costos del proyecto.
* Para ver las reclamaciones de gastos realizadas en un proyecto, haga clic en 'Reclamaciones de gastos'
<img class="screenshot" alt="Task - View Expense Claim" src="/docs/assets/img/project/task_view_expense_claim.png">
* También puede crear un Reclamo de gastos directamente y vincularlo al Proyecto.
<img class="screenshot" alt="Task - Link Expense Claim" src="/docs/assets/img/project/task_expense_claim_link.png">
* El monto total de los Reclamos de gastos reservados contra un proyecto se muestra en 'Reclamo de gastos totales' en la Sección de Costos del proyecto
<img class="screenshot" alt="Task - Total Expense Claim" src="/docs/assets/img/project/task_total_expense_claim.png">
{next}

View File

@@ -0,0 +1,25 @@
# Lote de registro de tiempo
Puede facturar Registros de tiempo viéndolos juntos. Esto le da la flexibilidad de administrar la facturación de su cliente de la manera que desee. Para crear una nueva hoja de tiempo, ve a
> Projects > Time Sheet > New Time Sheet
O
Simplemente abra su lista de registro de tiempo y marque los elementos que desea agregar al registro de tiempo. A continuación, haga clic en el botón "Crear hoja de tiempo" y se seleccionarán estos registros de tiempo.
<img class="screenshot" alt="Time Log - Drag Calender" src="/docs/assets/img/project/time_sheet.gif">
###Creando Factura de Venta
* Despues de crear la Hoja de Tiempo/Horario, el botón "Crear Factura" debe aparecer.
<img class="screenshot" alt="Time Log - Drag Calender" src="/docs/assets/img/project/time_sheet_make_invoice.png">
* Haga clic en ese botón para hacer una factura de venta usando la hoja de tiempo.
<img class="screenshot" alt="Time Log - Drag Calender" src="/docs/assets/img/project/time_sheet_sales_invoice.png">
* Cuando "Presente" la Factura de Ventas, el número de Factura de Ventas se actualizará en los Registros de Tiempo y la Hoja de Horario y su estado cambiará a "Facturado".
{next}

View File

@@ -139,6 +139,7 @@ var btn_create_vital_signs = function (frm) {
}
frappe.route_options = {
"patient": frm.doc.patient,
"appointment": frm.doc.appointment
};
frappe.new_doc("Vital Signs");
};

View File

@@ -216,7 +216,7 @@
"label": "Gender",
"length": 0,
"no_copy": 0,
"options": "\nMale\nFemale",
"options": "\nMale\nFemale\nOther",
"permlevel": 0,
"precision": "",
"print_hide": 1,
@@ -1004,7 +1004,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-10-05 12:13:52.596750",
"modified": "2017-11-22 14:03:30.434304",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Consultation",

View File

@@ -8,12 +8,12 @@ from frappe import _
from frappe.model.document import Document
from frappe.utils import getdate
import json
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account,get_income_account
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account, get_income_account
class Consultation(Document):
def on_update(self):
if(self.appointment):
frappe.db.set_value("Patient Appointment",self.appointment,"status","Closed")
frappe.db.set_value("Patient Appointment", self.appointment, "status", "Closed")
update_consultation_to_medical_record(self)
def after_insert(self):
@@ -23,9 +23,10 @@ class Consultation(Document):
if not self.diagnosis or not self.symptoms:
frappe.throw("Diagnosis and Complaints cannot be left blank")
physician = frappe.get_doc("Physician",self.physician)
if(frappe.session.user != physician.user_id):
frappe.throw(_("You don't have permission to submit"))
def on_cancel(self):
if(self.appointment):
frappe.db.set_value("Patient Appointment", self.appointment, "status", "Open")
delete_medical_record(self)
def set_sales_invoice_fields(company, patient):
sales_invoice = frappe.new_doc("Sales Invoice")
@@ -91,8 +92,8 @@ def create_invoice_items(physician, invoice, company):
item_line.qty = 1
item_line.uom = "Nos"
item_line.conversion_factor = 1
item_line.income_account = get_income_account(physician,company)
op_consulting_charge = frappe.get_value("Physician",physician,"op_consulting_charge")
item_line.income_account = get_income_account(physician, company)
op_consulting_charge = frappe.get_value("Physician", physician, "op_consulting_charge")
if op_consulting_charge:
item_line.rate = op_consulting_charge
item_line.amount = op_consulting_charge
@@ -111,10 +112,13 @@ def insert_consultation_to_medical_record(doc):
medical_record.save(ignore_permissions=True)
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))
medical_record_id = frappe.db.sql("select name from `tabPatient Medical Record` where reference_name=%s", (consultation.name))
if(medical_record_id[0][0]):
subject = set_subject_field(consultation)
frappe.db.set_value("Patient Medical Record",medical_record_id[0][0],"subject",subject)
frappe.db.set_value("Patient Medical Record", medical_record_id[0][0], "subject", subject)
def delete_medical_record(consultation):
frappe.db.sql("""delete from `tabPatient Medical Record` where reference_name = %s""", (consultation.name))
def set_subject_field(consultation):
subject = "No Diagnosis "

View File

@@ -9,6 +9,7 @@ frappe.ui.form.on('Healthcare Settings', {
filters: {
'account_type': 'Receivable',
'company': d.company,
'is_group': 0
}
};
});
@@ -18,6 +19,7 @@ frappe.ui.form.on('Healthcare Settings', {
filters: {
'root_type': 'Income',
'company': d.company,
'is_group': 0
}
};
});

View File

@@ -114,7 +114,7 @@
"columns": 0,
"fieldname": "patient_name",
"fieldtype": "Data",
"hidden": 1,
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
@@ -185,7 +185,7 @@
"label": "Gender",
"length": 0,
"no_copy": 0,
"options": "\nMale\nFemale",
"options": "\nMale\nFemale\nOther",
"permlevel": 0,
"precision": "",
"print_hide": 1,
@@ -1388,7 +1388,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-10-05 12:14:57.078823",
"modified": "2017-11-22 14:32:27.994634",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Lab Test",

View File

@@ -126,7 +126,7 @@
"label": "Gender",
"length": 0,
"no_copy": 0,
"options": "\nMale\nFemale",
"options": "\nMale\nFemale\nOther",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -185,7 +185,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "DOB",
"label": "Date of birth",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -353,37 +353,6 @@
"set_only_once": 1,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"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": "Company",
"length": 0,
"no_copy": 0,
"options": "Company",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 1,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -884,7 +853,7 @@
"label": "Marital Status",
"length": 0,
"no_copy": 0,
"options": "Single\nMarried\nDivorced\nWidow",
"options": "\nSingle\nMarried\nDivorced\nWidow",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -1274,7 +1243,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 50,
"modified": "2017-10-04 17:41:03.219934",
"modified": "2017-11-24 12:39:33.061005",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Patient",

View File

@@ -69,7 +69,10 @@ class Patient(Document):
frappe.db.set_value("Patient", self.name, "disabled", 0)
send_registration_sms(self)
if(frappe.get_value("Healthcare Settings", None, "registration_fee")>0):
sales_invoice = make_invoice(self.name, self.company)
company = frappe.defaults.get_user_default('company')
if not company:
company = frappe.db.get_value("Global Defaults", None, "default_company")
sales_invoice = make_invoice(self.name, company)
sales_invoice.save(ignore_permissions=True)
return {'invoice': sales_invoice.name}
@@ -110,7 +113,7 @@ def make_invoice(patient, company):
return sales_invoice
@frappe.whitelist()
def get_patient_detail(patient, company=None):
def get_patient_detail(patient):
patient_dict = frappe.db.sql("""select * from tabPatient where name=%s""", (patient), as_dict=1)
if not patient_dict:
frappe.throw("Patient not found")

View File

@@ -11,8 +11,8 @@ def get_data():
'items': ['Patient Appointment', 'Consultation']
},
{
'label': _('Lab Tests'),
'items': ['Lab Test']
'label': _('Lab Tests and Vital Signs'),
'items': ['Lab Test', 'Vital Signs']
}
]
}

View File

@@ -25,6 +25,14 @@ frappe.ui.form.on('Patient Appointment', {
frm.add_custom_button(__('Cancel'), function() {
btn_update_status(frm, "Cancelled");
});
frm.add_custom_button(__("Consultation"),function(){
btn_create_consultation(frm);
},"Create");
frm.add_custom_button(__('Vital Signs'), function() {
btn_create_vital_signs(frm);
},"Create");
}
if(frm.doc.status == "Scheduled" && !frm.doc.__islocal){
frm.add_custom_button(__('Cancel'), function() {
@@ -177,6 +185,7 @@ var btn_create_vital_signs = function (frm) {
}
frappe.route_options = {
"patient": frm.doc.patient,
"appointment": frm.doc.name,
};
frappe.new_doc("Vital Signs");
};

View File

@@ -165,6 +165,100 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "patient_name",
"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": "Patient Name",
"length": 0,
"no_copy": 0,
"options": "patient.patient_name",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "patient_sex",
"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": "Gender",
"length": 0,
"no_copy": 1,
"options": "patient.sex",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 1,
"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": "patient_age",
"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": "Patient Age",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -440,158 +534,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_2",
"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,
"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": "patient_details",
"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": "Patient Details",
"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": "patient",
"fieldname": "patient_name",
"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": "Patient Name",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "patient_sex",
"fieldtype": "Data",
"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": "Gender",
"length": 0,
"no_copy": 1,
"options": "patient.sex",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 1,
"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": "patient_age",
"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": "Patient Age",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -756,7 +698,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-10-25 23:33:36.060803",
"modified": "2017-11-22 16:32:57.240736",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Patient Appointment",

View File

@@ -56,7 +56,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Patient",
"length": 0,
@@ -174,7 +174,7 @@
"ignore_xss_filter": 1,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Subject",
"length": 0,
@@ -236,7 +236,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Datetime",
"length": 0,
@@ -266,7 +266,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Reference DocType",
"length": 0,
@@ -297,7 +297,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Reference Name",
"length": 0,
@@ -389,7 +389,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-10-04 16:09:55.597866",
"modified": "2017-11-15 12:48:59.945615",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Patient Medical Record",
@@ -425,6 +425,7 @@
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "patient",
"track_changes": 1,
"track_seen": 1
}

View File

@@ -9,6 +9,7 @@ frappe.ui.form.on('Physician', {
filters: {
'root_type': 'Income',
'company': d.company,
'is_group': 0
}
};
});

View File

@@ -33,7 +33,7 @@ frappe.ui.form.on('Physician Schedule', {
while(cur_time < end_time) {
let to_time = cur_time.clone().add(values.duration, 'minutes');
if(to_time < end_time) {
if(to_time <= end_time) {
// add a new timeslot
frm.add_child('time_slots', {

View File

@@ -43,6 +43,37 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "patient_name",
"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": "Patient Name",
"length": 0,
"no_copy": 0,
"options": "patient.patient_name",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -751,7 +782,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-10-04 16:08:36.340607",
"modified": "2017-11-22 17:31:16.620650",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Vital Signs",

View File

@@ -87,22 +87,24 @@ frappe.ui.form.on('Employee Loan', {
},
employee_loan_application: function (frm) {
return frappe.call({
method: "erpnext.hr.doctype.employee_loan.employee_loan.get_employee_loan_application",
args: {
"employee_loan_application": frm.doc.employee_loan_application
},
callback: function (r) {
if (!r.exc && r.message) {
frm.set_value("loan_type", r.message.loan_type);
frm.set_value("loan_amount", r.message.loan_amount);
frm.set_value("repayment_method", r.message.repayment_method);
frm.set_value("monthly_repayment_amount", r.message.repayment_amount);
frm.set_value("repayment_periods", r.message.repayment_periods);
frm.set_value("rate_of_interest", r.message.rate_of_interest);
}
}
})
if(frm.doc.employee_loan_application){
return frappe.call({
method: "erpnext.hr.doctype.employee_loan.employee_loan.get_employee_loan_application",
args: {
"employee_loan_application": frm.doc.employee_loan_application
},
callback: function (r) {
if (!r.exc && r.message) {
frm.set_value("loan_type", r.message.loan_type);
frm.set_value("loan_amount", r.message.loan_amount);
frm.set_value("repayment_method", r.message.repayment_method);
frm.set_value("monthly_repayment_amount", r.message.repayment_amount);
frm.set_value("repayment_periods", r.message.repayment_periods);
frm.set_value("rate_of_interest", r.message.rate_of_interest);
}
}
});
}
},
repayment_method: function (frm) {

View File

@@ -38,9 +38,8 @@ class TestEmployeeLoan(unittest.TestCase):
self.assertEquals(employee_loan.total_interest_payable, 22712)
self.assertEquals(employee_loan.total_payment, 302712)
def create_loan_type(loan_name, maximum_loan_amount, rate_of_interest):
if not frappe.db.get_value("Loan Type", loan_name):
if not frappe.db.exists("Loan Type", loan_name):
frappe.get_doc({
"doctype": "Loan Type",
"loan_name": loan_name,
@@ -49,6 +48,7 @@ def create_loan_type(loan_name, maximum_loan_amount, rate_of_interest):
}).insert()
def create_employee_loan(employee, loan_type, loan_amount, repayment_method, repayment_periods):
create_loan_type(loan_type, 500000, 8.4)
if not frappe.db.get_value("Employee Loan", {"employee":employee}):
employee_loan = frappe.new_doc("Employee Loan")
employee_loan.update({

View File

@@ -13,35 +13,6 @@
"editable_grid": 0,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -507,7 +478,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-06-13 14:29:01.066538",
"modified": "2017-11-10 18:41:38.845159",
"modified_by": "Administrator",
"module": "HR",
"name": "Leave Allocation",

View File

@@ -11,34 +11,7 @@
"editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -69,6 +42,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -99,6 +73,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -129,6 +104,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -159,6 +135,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -189,6 +166,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -217,6 +195,7 @@
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -246,6 +225,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -275,6 +255,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -304,6 +285,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -333,6 +315,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -361,6 +344,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -401,7 +385,7 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
"modified": "2017-03-29 11:24:17.013862",
"modified": "2017-11-10 18:42:17.060492",
"modified_by": "Administrator",
"module": "HR",
"name": "Leave Control Panel",

View File

@@ -27,13 +27,13 @@ QUnit.test("Test: Offer Letter [HR]", function (assert) {
]},
]);
},
() => frappe.timeout(12),
() => frappe.timeout(10),
() => frappe.click_button('Submit'),
() => frappe.timeout(2),
() => frappe.click_button('Yes'),
() => frappe.timeout(8),
() => frappe.timeout(5),
// To check if the fields are correctly set
() => {
// To check if the fields are correctly set
assert.ok(cur_frm.get_field('status').value=='Accepted',
'Status of job offer is correct');
assert.ok(cur_frm.get_field('designation').value=='Software Developer',
@@ -45,7 +45,7 @@ QUnit.test("Test: Offer Letter [HR]", function (assert) {
() => {
assert.ok(cur_list.data[0].docstatus==1,'Offer Letter Submitted successfully');
},
() => frappe.timeout(4),
() => frappe.timeout(2),
() => done()
]);
});

View File

@@ -190,23 +190,28 @@ class ProcessPayroll(Document):
def format_as_links(self, salary_slip):
return ['<a href="#Form/Salary Slip/{0}">{0}</a>'.format(salary_slip)]
def get_total_salary_and_loan_amounts(self):
def get_loan_details(self):
"""
Get total loan principal, loan interest and salary amount from submitted salary slip based on selected criteria
Get loan details from submitted salary slip based on selected criteria
"""
cond = self.get_filter_condition()
totals = frappe.db.sql("""
select sum(principal_amount) as total_principal_amount, sum(interest_amount) as total_interest_amount,
sum(total_loan_repayment) as total_loan_repayment, sum(rounded_total) as rounded_total from `tabSalary Slip` t1
return frappe.db.sql(""" select eld.employee_loan_account,
eld.interest_income_account, eld.principal_amount, eld.interest_amount, eld.total_payment
from
`tabSalary Slip` t1, `tabSalary Slip Loan` eld
where
t1.docstatus = 1 and t1.name = eld.parent and start_date >= %s and end_date <= %s %s
""" % ('%s', '%s', cond), (self.start_date, self.end_date), as_dict=True) or []
def get_total_salary_amount(self):
"""
Get total salary amount from submitted salary slip based on selected criteria
"""
cond = self.get_filter_condition()
totals = frappe.db.sql(""" select sum(rounded_total) as rounded_total from `tabSalary Slip` t1
where t1.docstatus = 1 and start_date >= %s and end_date <= %s %s
""" % ('%s', '%s', cond), (self.start_date, self.end_date), as_dict=True)
return totals[0]
def get_loan_accounts(self):
loan_accounts = frappe.get_all("Employee Loan", fields=["employee_loan_account", "interest_income_account"],
filters = {"company": self.company, "docstatus":1})
if loan_accounts:
return loan_accounts[0]
return totals and totals[0] or None
def get_salary_component_account(self, salary_component):
account = frappe.db.get_value("Salary Component Account",
@@ -257,8 +262,7 @@ class ProcessPayroll(Document):
earnings = self.get_salary_component_total(component_type = "earnings") or {}
deductions = self.get_salary_component_total(component_type = "deductions") or {}
default_payroll_payable_account = self.get_default_payroll_payable_account()
loan_amounts = self.get_total_salary_and_loan_amounts()
loan_accounts = self.get_loan_accounts()
loan_details = self.get_loan_details()
jv_name = ""
precision = frappe.get_precision("Journal Entry Account", "debit_in_account_currency")
@@ -294,18 +298,18 @@ class ProcessPayroll(Document):
})
# Employee loan
if loan_amounts.total_loan_repayment:
for data in loan_details:
accounts.append({
"account": loan_accounts.employee_loan_account,
"credit_in_account_currency": loan_amounts.total_principal_amount
"account": data.employee_loan_account,
"credit_in_account_currency": data.principal_amount
})
accounts.append({
"account": loan_accounts.interest_income_account,
"credit_in_account_currency": loan_amounts.total_interest_amount,
"account": data.interest_income_account,
"credit_in_account_currency": data.interest_amount,
"cost_center": self.cost_center,
"project": self.project
})
payable_amount -= flt(loan_amounts.total_loan_repayment, precision)
payable_amount -= flt(data.total_payment, precision)
# Payable amount
accounts.append({
@@ -327,11 +331,11 @@ class ProcessPayroll(Document):
def make_payment_entry(self):
self.check_permission('write')
total_salary_amount = self.get_total_salary_and_loan_amounts()
total_salary_amount = self.get_total_salary_amount()
default_payroll_payable_account = self.get_default_payroll_payable_account()
precision = frappe.get_precision("Journal Entry Account", "debit_in_account_currency")
if total_salary_amount.rounded_total:
if total_salary_amount and total_salary_amount.rounded_total:
journal_entry = frappe.new_doc('Journal Entry')
journal_entry.voucher_type = 'Bank Entry'
journal_entry.user_remark = _('Payment of salary from {0} to {1}')\

View File

@@ -6,9 +6,9 @@ import unittest
import erpnext
import frappe
from frappe.utils import nowdate
from erpnext.hr.doctype.process_payroll.process_payroll import get_end_date
from dateutil.relativedelta import relativedelta
from erpnext.accounts.utils import get_fiscal_year, getdate, nowdate
from erpnext.hr.doctype.process_payroll.process_payroll import get_start_end_dates, get_end_date
class TestProcessPayroll(unittest.TestCase):
def test_process_payroll(self):
@@ -19,22 +19,9 @@ class TestProcessPayroll(unittest.TestCase):
if not frappe.db.get_value('Salary Component Account',
{'parent': data.name, 'company': erpnext.get_default_company()}, 'name'):
get_salary_component_account(data.name)
payment_account = frappe.get_value('Account',
{'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name")
if not frappe.db.get_value("Salary Slip", {"start_date": "2016-11-01", "end_date": "2016-11-30"}):
process_payroll = frappe.get_doc("Process Payroll", "Process Payroll")
process_payroll.company = erpnext.get_default_company()
process_payroll.start_date = "2016-11-01"
process_payroll.end_date = "2016-11-30"
process_payroll.payment_account = payment_account
process_payroll.posting_date = nowdate()
process_payroll.payroll_frequency = "Monthly"
process_payroll.create_salary_slips()
process_payroll.submit_salary_slips()
if process_payroll.get_sal_slip_list(ss_status = 1):
r = process_payroll.make_payment_entry()
make_process_payroll()
def test_get_end_date(self):
self.assertEqual(get_end_date('2017-01-01', 'monthly'), {'end_date': '2017-01-31'})
@@ -45,7 +32,99 @@ class TestProcessPayroll(unittest.TestCase):
self.assertEqual(get_end_date('2020-02-15', 'bimonthly'), {'end_date': ''})
self.assertEqual(get_end_date('2017-02-15', 'monthly'), {'end_date': '2017-03-14'})
self.assertEqual(get_end_date('2017-02-15', 'daily'), {'end_date': '2017-02-15'})
def test_employee_loan(self):
from erpnext.hr.doctype.salary_structure.test_salary_structure import (make_employee,
make_salary_structure)
from erpnext.hr.doctype.employee_loan.test_employee_loan import create_employee_loan
branch = "Test Employee Branch"
employee = make_employee("test_employee@loan.com")
company = erpnext.get_default_company()
holiday_list = make_holiday("test holiday for loan")
if not frappe.db.exists('Salary Component', 'Basic Salary'):
frappe.get_doc({
'doctype': 'Salary Component',
'salary_component': 'Basic Salary',
'salary_component_abbr': 'BS',
'type': 'Earning',
'accounts': [{
'company': company,
'default_account': frappe.db.get_value('Account',
{'company': company, 'root_type': 'Expense', 'account_type': ''}, 'name')
}]
}).insert()
if not frappe.db.get_value('Salary Component Account',
{'parent': 'Basic Salary', 'company': company}):
salary_component = frappe.get_doc('Salary Component', 'Basic Salary')
salary_component.append('accounts', {
'company': company,
'default_account': 'Salary - WP'
})
company_doc = frappe.get_doc('Company', company)
if not company_doc.default_payroll_payable_account:
company_doc.default_payroll_payable_account = frappe.db.get_value('Account',
{'company': company, 'root_type': 'Liability', 'account_type': ''}, 'name')
company_doc.save()
if not frappe.db.exists('Branch', branch):
frappe.get_doc({
'doctype': 'Branch',
'branch': branch
}).insert()
employee_doc = frappe.get_doc('Employee', employee)
employee_doc.branch = branch
employee_doc.holiday_list = holiday_list
employee_doc.save()
employee_loan = create_employee_loan(employee,
"Personal Loan", 280000, "Repay Over Number of Periods", 20)
employee_loan.repay_from_salary = 1
employee_loan.submit()
salary_strcture = "Test Salary Structure for Loan"
if not frappe.db.exists('Salary Structure', salary_strcture):
salary_strcture = make_salary_structure(salary_strcture, [{
'employee': employee,
'from_date': '2017-01-01',
'base': 30000
}])
salary_strcture = frappe.get_doc('Salary Structure', salary_strcture)
salary_strcture.set('earnings', [{
'salary_component': 'Basic Salary',
'abbr': 'BS',
'amount_based_on_formula':1,
'formula': 'base*.5'
}])
salary_strcture.save()
dates = get_start_end_dates('Monthly', nowdate())
make_process_payroll(start_date=dates.start_date,
end_date=dates.end_date, branch=branch)
name = frappe.db.get_value('Salary Slip',
{'posting_date': nowdate(), 'employee': employee}, 'name')
salary_slip = frappe.get_doc('Salary Slip', name)
for row in salary_slip.loans:
if row.employee_loan == employee_loan.name:
interest_amount = (280000 * 8.4)/(12*100)
principal_amount = employee_loan.monthly_repayment_amount - interest_amount
self.assertEqual(row.interest_amount, interest_amount)
self.assertEqual(row.principal_amount, principal_amount)
self.assertEqual(row.total_payment,
interest_amount + principal_amount)
if salary_slip.docstatus == 0:
frappe.delete_doc('Salary Slip', name)
employee_loan.cancel()
frappe.delete_doc('Employee Loan', employee_loan.name)
def get_salary_component_account(sal_comp):
company = erpnext.get_default_company()
@@ -63,4 +142,54 @@ def create_account(company):
"parent_account": "Indirect Expenses - " + frappe.db.get_value('Company', company, 'abbr'),
"company": company
}).insert()
return salary_account
return salary_account
def make_process_payroll(**args):
args = frappe._dict(args)
process_payroll = frappe.get_doc("Process Payroll", "Process Payroll")
process_payroll.company = erpnext.get_default_company()
process_payroll.start_date = args.start_date or "2016-11-01"
process_payroll.end_date = args.end_date or "2016-11-30"
process_payroll.payment_account = get_payment_account()
process_payroll.posting_date = nowdate()
process_payroll.payroll_frequency = "Monthly"
process_payroll.branch = args.branch or None
process_payroll.create_salary_slips()
process_payroll.submit_salary_slips()
if process_payroll.get_sal_slip_list(ss_status = 1):
r = process_payroll.make_payment_entry()
return process_payroll
def get_payment_account():
return frappe.get_value('Account',
{'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name")
def make_holiday(holiday_list_name):
if not frappe.db.exists('Holiday List', holiday_list_name):
current_fiscal_year = get_fiscal_year(nowdate(), as_dict=True)
dt = getdate(nowdate())
new_year = dt + relativedelta(month=01, day=01, year=dt.year)
republic_day = dt + relativedelta(month=01, day=26, year=dt.year)
test_holiday = dt + relativedelta(month=02, day=02, year=dt.year)
frappe.get_doc({
'doctype': 'Holiday List',
'from_date': current_fiscal_year.year_start_date,
'to_date': current_fiscal_year.year_end_date,
'holiday_list_name': holiday_list_name,
'holidays': [{
'holiday_date': new_year,
'description': 'New Year'
}, {
'holiday_date': republic_day,
'description': 'Republic Day'
}, {
'holiday_date': test_holiday,
'description': 'Test Holiday'
}]
}).insert()
return holiday_list_name

View File

@@ -161,18 +161,15 @@ var calculate_earning_total = function(doc, dt, dn, reset_amount) {
tbl[i].amount = Math.round(tbl[i].default_amount)*(flt(doc.payment_days) /
cint(doc.total_working_days)*100)/100;
refresh_field('amount', tbl[i].name, 'earnings');
} else if(reset_amount) {
tbl[i].amount = tbl[i].default_amount;
refresh_field('amount', tbl[i].name, 'earnings');
}
if(!tbl[i].do_not_include_in_total) {
total_earn += flt(tbl[i].amount);
}
}
doc.gross_pay = total_earn;
refresh_many(['amount','gross_pay']);
refresh_many(['earnings', 'amount','gross_pay']);
}
// Calculate deduction total
@@ -183,17 +180,15 @@ var calculate_ded_total = function(doc, dt, dn, reset_amount) {
for(var i = 0; i < tbl.length; i++){
if(cint(tbl[i].depends_on_lwp) == 1) {
tbl[i].amount = Math.round(tbl[i].default_amount)*(flt(doc.payment_days)/cint(doc.total_working_days)*100)/100;
refresh_field('amount', tbl[i].name, 'deductions');
} else if(reset_amount) {
tbl[i].amount = tbl[i].default_amount;
refresh_field('amount', tbl[i].name, 'deductions');
}
if(!tbl[i].do_not_include_in_total) {
total_ded += flt(tbl[i].amount);
}
}
doc.total_deduction = total_ded;
refresh_field('total_deduction');
refresh_many(['deductions', 'total_deduction']);
}
// Calculate net payable amount

View File

@@ -1,5 +1,6 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
@@ -12,35 +13,7 @@
"editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break0",
"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,
"oldfieldtype": "Column Break",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -53,7 +26,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Posting Date",
"length": 0,
@@ -71,6 +44,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -82,7 +56,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 1,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Employee",
"length": 0,
@@ -102,6 +76,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -113,7 +88,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 1,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Employee Name",
"length": 0,
@@ -133,6 +108,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -164,6 +140,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -196,6 +173,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -227,6 +205,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -256,6 +235,7 @@
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -286,6 +266,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -316,6 +297,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -327,7 +309,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Company",
"length": 0,
@@ -345,6 +327,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
@@ -374,6 +357,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -402,6 +386,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -433,6 +418,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -463,6 +449,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -494,6 +481,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -522,6 +510,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -553,6 +542,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -585,6 +575,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -616,6 +607,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -647,6 +639,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -678,6 +671,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -708,6 +702,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -739,6 +734,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -767,6 +763,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -796,6 +793,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -826,6 +824,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -856,6 +855,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -886,6 +886,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -916,6 +917,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -944,6 +946,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -975,6 +978,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1004,6 +1008,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1034,6 +1039,7 @@
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1066,6 +1072,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1096,6 +1103,7 @@
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1127,6 +1135,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1156,6 +1165,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1187,6 +1197,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1214,6 +1225,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1245,6 +1257,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1275,11 +1288,73 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "principal_amount",
"fieldname": "loans",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Employee Loan",
"length": 0,
"no_copy": 0,
"options": "Salary Slip Loan",
"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,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_43",
"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,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"fieldname": "total_principal_amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -1288,7 +1363,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Principal Amount",
"label": "Total Principal Amount",
"length": 0,
"no_copy": 0,
"options": "Company:company:default_currency",
@@ -1305,11 +1380,13 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "interest_amount",
"default": "0",
"fieldname": "total_interest_amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -1318,7 +1395,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Interest Amount",
"label": "Total Interest Amount",
"length": 0,
"no_copy": 0,
"options": "Company:company:default_currency",
@@ -1335,11 +1412,12 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_48",
"fieldname": "column_break_45",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -1363,10 +1441,12 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"fieldname": "total_loan_repayment",
"fieldtype": "Currency",
"hidden": 0,
@@ -1393,6 +1473,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1422,6 +1503,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1454,6 +1536,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1482,6 +1565,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -1511,6 +1595,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1539,6 +1624,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1570,18 +1656,18 @@
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-file-text",
"idx": 9,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 1,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-03-02 02:25:53.844701",
"modified": "2017-11-13 23:55:37.504856",
"modified_by": "Administrator",
"module": "HR",
"name": "Salary Slip",

View File

@@ -348,7 +348,8 @@ class SalarySlip(TransactionBase):
/ cint(self.total_working_days)), self.precision("amount", component_type)
)
elif not self.payment_days and not self.salary_slip_based_on_timesheet:
elif not self.payment_days and not self.salary_slip_based_on_timesheet and \
cint(d.depends_on_lwp):
d.amount = 0
elif not d.amount:
d.amount = d.default_amount
@@ -374,15 +375,34 @@ class SalarySlip(TransactionBase):
self.precision("net_pay") if disable_rounded_total else 0)
def set_loan_repayment(self):
employee_loan = frappe.db.sql("""select sum(principal_amount) as principal_amount, sum(interest_amount) as interest_amount,
sum(total_payment) as total_loan_repayment from `tabRepayment Schedule`
where payment_date between %s and %s and parent in (select name from `tabEmployee Loan`
where employee = %s and repay_from_salary = 1 and docstatus = 1)""",
(self.start_date, self.end_date, self.employee), as_dict=True)
if employee_loan:
self.principal_amount = employee_loan[0].principal_amount
self.interest_amount = employee_loan[0].interest_amount
self.total_loan_repayment = employee_loan[0].total_loan_repayment
self.set('loans', [])
self.total_loan_repayment = 0
self.total_interest_amount = 0
self.total_principal_amount = 0
for loan in self.get_employee_loan_details():
self.append('loans', {
'employee_loan': loan.name,
'total_payment': loan.total_payment,
'interest_amount': loan.interest_amount,
'principal_amount': loan.principal_amount,
'employee_loan_account': loan.employee_loan_account,
'interest_income_account': loan.interest_income_account
})
self.total_loan_repayment += loan.total_payment
self.total_interest_amount += loan.interest_amount
self.total_principal_amount += loan.principal_amount
def get_employee_loan_details(self):
return frappe.db.sql("""select rps.principal_amount, rps.interest_amount, el.name,
rps.total_payment, el.employee_loan_account, el.interest_income_account
from
`tabRepayment Schedule` as rps, `tabEmployee Loan` as el
where
el.name = rps.parent and rps.payment_date between %s and %s and
el.repay_from_salary = 1 and el.docstatus = 1 and el.employee = %s""",
(self.start_date, self.end_date, self.employee), as_dict=True) or []
def on_submit(self):
if self.net_pay < 0:

View File

@@ -0,0 +1,256 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2017-11-08 12:51:12.834479",
"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": "employee_loan",
"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": "Employee Loan",
"length": 0,
"no_copy": 0,
"options": "Employee Loan",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"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": "employee_loan_account",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Employee Loan Account",
"length": 0,
"no_copy": 0,
"options": "Account",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "interest_income_account",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Interest Income Account",
"length": 0,
"no_copy": 0,
"options": "Account",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_4",
"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": "principal_amount",
"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": "Principal Amount",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "interest_amount",
"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": "Interest Amount",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_payment",
"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": "Total Payment",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2017-11-13 23:59:47.237689",
"modified_by": "Administrator",
"module": "HR",
"name": "Salary Slip Loan",
"name_case": "",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0
}

View File

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

View File

@@ -1,5 +1,6 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
"autoname": "Prompt",
@@ -12,34 +13,7 @@
"editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -69,6 +43,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -99,6 +74,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -127,6 +103,7 @@
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -159,6 +136,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -191,6 +169,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -222,6 +201,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -250,6 +230,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -281,6 +262,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -310,6 +292,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -340,6 +323,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -368,6 +352,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -400,6 +385,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -431,6 +417,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -464,6 +451,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -495,6 +483,7 @@
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -527,6 +516,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -558,6 +548,7 @@
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -589,6 +580,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -618,6 +610,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -646,6 +639,7 @@
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -677,6 +671,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -708,6 +703,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -737,6 +733,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -766,6 +763,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -796,6 +794,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -824,6 +823,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -854,18 +854,18 @@
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-file-text",
"idx": 1,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-02-22 06:09:55.491748",
"modified": "2017-11-10 18:45:07.120254",
"modified_by": "Administrator",
"module": "HR",
"name": "Salary Structure",

View File

@@ -17,11 +17,9 @@ class TestSalaryStructure(unittest.TestCase):
def setUp(self):
self.make_holiday_list()
frappe.db.set_value("Company", erpnext.get_default_company(), "default_holiday_list", "Salary Structure Test Holiday List")
make_earning_salary_component(["Basic Salary", "Special Allowance", "HRA"])
make_deduction_salary_component(["Professional Tax", "TDS"])
make_employee("test_employee@salary.com")
make_employee("test_employee_2@salary.com")
def make_holiday_list(self):
if not frappe.db.get_value("Holiday List", "Salary Structure Test Holiday List"):
holiday_list = frappe.get_doc({
@@ -33,7 +31,7 @@ class TestSalaryStructure(unittest.TestCase):
}).insert()
holiday_list.get_weekly_off_dates()
holiday_list.save()
def test_amount_totals(self):
sal_slip = frappe.get_value("Salary Slip", {"employee_name":"test_employee@salary.com"})
if not sal_slip:
@@ -64,7 +62,7 @@ class TestSalaryStructure(unittest.TestCase):
for row in salary_structure.deductions:
self.assertFalse(("\n" in row.formula) or ("\n" in row.condition))
def make_employee(user):
if not frappe.db.get_value("User", user):
frappe.get_doc({
@@ -74,7 +72,6 @@ def make_employee(user):
"new_password": "password",
"roles": [{"doctype": "Has Role", "role": "Employee"}]
}).insert()
if not frappe.db.get_value("Employee", {"user_id": user}):
emp = frappe.get_doc({
@@ -95,7 +92,7 @@ def make_employee(user):
return emp.name
else:
return frappe.get_value("Employee", {"employee_name":user}, "name")
def make_salary_slip_from_salary_structure(employee):
sal_struct = make_salary_structure('Salary Structure Sample')
sal_slip = make_salary_slip(sal_struct, employee = employee)
@@ -106,22 +103,21 @@ def make_salary_slip_from_salary_structure(employee):
sal_slip.insert()
sal_slip.submit()
return sal_slip
def make_salary_structure(sal_struct):
def make_salary_structure(sal_struct, employees=None):
if not frappe.db.exists('Salary Structure', sal_struct):
frappe.get_doc({
"doctype": "Salary Structure",
"name": sal_struct,
"company": erpnext.get_default_company(),
"employees": get_employee_details(),
"employees": employees or get_employee_details(),
"earnings": get_earnings_component(),
"deductions": get_deductions_component(),
"payroll_frequency": "Monthly",
"payment_account": frappe.get_value('Account', {'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name")
}).insert()
return sal_struct
return sal_struct
def get_employee_details():
return [{"employee": frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"),
"base": 25000,
@@ -136,8 +132,11 @@ def get_employee_details():
"idx": 2
}
]
def get_earnings_component():
def get_earnings_component():
make_earning_salary_component(["Basic Salary", "Special Allowance", "HRA"])
make_deduction_salary_component(["Professional Tax", "TDS"])
return [
{
"salary_component": 'Basic Salary',
@@ -167,7 +166,7 @@ def get_earnings_component():
"idx": 4
},
]
def get_deductions_component():
return [
{
@@ -191,5 +190,4 @@ def get_deductions_component():
"formula": 'base*.1',
"idx": 3
}
]
]

View File

@@ -1,7 +1,7 @@
QUnit.module('hr');
QUnit.test("Test: Training Event [HR]", function (assert) {
assert.expect(4);
assert.expect(5);
let done = assert.async();
let employee_name;
@@ -21,7 +21,8 @@ QUnit.test("Test: Training Event [HR]", function (assert) {
{ employees: [
[
{employee: employee_name},
{employee_name: 'Test Employee 1'}
{employee_name: 'Test Employee 1'},
{attendance: 'Optional'}
]
]},
]);
@@ -41,6 +42,9 @@ QUnit.test("Test: Training Event [HR]", function (assert) {
assert.ok(cur_frm.doc.employees[0].employee_name=='Test Employee 1',
'Attendee Employee is correctly set');
assert.ok(cur_frm.doc.employees[0].attendance=='Optional',
'Attendance is correctly set');
},
() => frappe.set_route('List','Training Event','List'),

View File

@@ -1,40 +0,0 @@
QUnit.module('hr');
QUnit.test("test: Training Event", function (assert) {
// number of asserts
assert.expect(1);
let done = assert.async();
frappe.run_serially([
// insert a new Training Event
() => frappe.set_route("List", "Training Event", "List"),
() => frappe.new_doc("Training Event"),
() => frappe.timeout(1),
() => frappe.click_link('Edit in full page'),
() => cur_frm.set_value("event_name", "Test Event " + frappe.utils.get_random(10)),
() => cur_frm.set_value("start_time", "2017-07-26, 2:00 pm PDT"),
() => cur_frm.set_value("end_time", "2017-07-26, 2:30 pm PDT"),
() => cur_frm.set_value("introduction", "This is a test report"),
() => cur_frm.set_value("location", "Fake office"),
() => frappe.click_button('Add Row'),
() => frappe.db.get_value('Employee', {'employee_name':'Test Employee 1'}, 'name'),
(r) => {
console.log(r);
return cur_frm.fields_dict.employees.grid.grid_rows[0].doc.employee = r.message.name;
},
() => {
return cur_frm.fields_dict.employees.grid.grid_rows[0].doc.attendance = "Optional";
},
() => frappe.click_button('Save'),
() => frappe.timeout(2),
() => frappe.click_button('Submit'),
() => frappe.timeout(2),
() => frappe.click_button('Yes'),
() => frappe.timeout(1),
() => {
assert.equal(cur_frm.doc.docstatus, 1);
},
() => done()
]);
});

View File

@@ -809,7 +809,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-10-18 11:22:20.143491",
"modified": "2017-10-23 06:13:29.065781",
"modified_by": "Administrator",
"module": "HR",
"name": "Training Event",
@@ -837,7 +837,7 @@
"write": 1
}
],
"quick_entry": 1,
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"search_fields": "event_name",

View File

@@ -5,7 +5,7 @@ def get_data():
'fieldname': 'training_program',
'transactions': [
{
'label': _('Training Event'),
'label': _('Training Events'),
'items': ['Training Event']
},
]

View File

@@ -34,7 +34,9 @@ def get_categories():
return response
@frappe.whitelist()
def get_item_details(hub_sync_id):
def get_item_details(hub_sync_id=None):
if not hub_sync_id:
return
connection = get_connection()
return connection.get_doc('Hub Item', hub_sync_id)

View File

@@ -382,6 +382,7 @@ erpnext.hub.Hub = class Hub {
},
method: "erpnext.hub_node.get_item_details",
callback: (r) => {
if (!r || !r.message) return;
let item = r.message;
this.item_cache[item_code] = item;
this.render_item_page(item);
@@ -483,7 +484,7 @@ erpnext.hub.Hub = class Hub {
}
frappe.call({
method: 'erpnext.hub_node.get_company_details',
args: {company_id: company_id}
args: {hub_sync_id: company_id}
}).then((r) => {
if (r.message) {
const company_details = r.message.company_details;

View File

@@ -519,6 +519,7 @@ def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_ite
# Did not use qty_consumed_per_unit in the query, as it leads to rounding loss
query = """select
bom_item.item_code,
bom_item.idx,
item.item_name,
sum(bom_item.stock_qty/ifnull(bom.quantity, 1)) * %(qty)s as qty,
item.description,

View File

@@ -157,6 +157,7 @@ frappe.ui.form.on("Production Order", {
item: frm.doc.production_item,
project: frm.doc.project
},
freeze: true,
callback: function(r) {
if(r.message) {
erpnext.in_production_item_onchange = true;
@@ -184,6 +185,7 @@ frappe.ui.form.on("Production Order", {
return frm.call({
doc: frm.doc,
method: "get_items_and_operations_from_bom",
freeze: true,
callback: function(r) {
if(r.message["set_scrap_wh_mandatory"]){
frm.toggle_reqd("scrap_warehouse", true);

View File

@@ -43,10 +43,7 @@ class ProductionOrder(Document):
validate_uom_is_integer(self, "stock_uom", ["qty", "produced_qty"])
if not self.get("required_items"):
self.set_required_items()
else:
self.set_available_qty()
self.set_required_items(reset_only_qty = len(self.get("required_items")))
def validate_sales_order(self):
if self.sales_order:
@@ -57,6 +54,19 @@ class ProductionOrder(Document):
and so.docstatus = 1 and so_item.item_code=%s
""", (self.sales_order, self.production_item), as_dict=1)
if not so:
so = frappe.db.sql("""
select
so.name, so_item.delivery_date, so.project
from
`tabSales Order` so, `tabSales Order Item` so_item, `tabPacked Item` packed_item
where so.name=%s
and so.name=so_item.parent
and so.name=packed_item.parent
and so_item.item_code = packed_item.parent_item
and so.docstatus = 1 and packed_item.item_code=%s
""", (self.sales_order, self.production_item), as_dict=1)
if len(so):
if not self.expected_delivery_date:
self.expected_delivery_date = so[0].delivery_date
@@ -431,19 +441,27 @@ class ProductionOrder(Document):
if self.wip_warehouse:
d.available_qty_at_wip_warehouse = get_latest_stock_qty(d.item_code, self.wip_warehouse)
def set_required_items(self):
def set_required_items(self, reset_only_qty=False):
'''set required_items for production to keep track of reserved qty'''
self.required_items = []
if not reset_only_qty:
self.required_items = []
if self.bom_no and self.qty:
item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=self.qty,
fetch_exploded = self.use_multi_level_bom)
for item in sorted(item_dict.values(), key=lambda d: d['idx']):
self.append('required_items', {
'item_code': item.item_code,
'required_qty': item.qty,
'source_warehouse': item.source_warehouse or item.default_warehouse
})
if reset_only_qty:
for d in self.get("required_items"):
d.required_qty = item_dict.get(d.item_code).get("qty")
else:
for item in sorted(item_dict.values(), key=lambda d: d['idx']):
self.append('required_items', {
'item_code': item.item_code,
'item_name': item.item_name,
'description': item.description,
'required_qty': item.qty,
'source_warehouse': item.source_warehouse or item.default_warehouse
})
self.set_available_qty()

View File

@@ -15,62 +15,66 @@ def get_item_list(prod_list, filters):
out = []
#Add a row for each item/qty
for prod_order in prod_list:
prod_details = frappe.db.get_value("Production Order", prod_order.name,
["bom_no", "source_warehouse", "qty", "produced_qty"], as_dict=1)
for prod_details in prod_list:
desc = frappe.db.get_value("BOM", prod_details.bom_no, "description")
item_list = frappe.db.sql("""SELECT
bom_item.item_code as item_code,
ifnull(ledger.actual_qty*bom.quantity/bom_item.stock_qty,0) as build_qty
FROM
`tabBOM` as bom, `tabBOM Item` AS bom_item
LEFT JOIN `tabBin` AS ledger
ON bom_item.item_code = ledger.item_code
AND ledger.warehouse = ifnull(%(warehouse)s,%(filterhouse)s)
WHERE
bom.name = bom_item.parent
and bom.name = %(bom)s
GROUP BY
bom_item.item_code""",
{"bom": prod_details.bom_no, "warehouse": prod_details.source_warehouse,
"filterhouse": filters.warehouse}, as_dict=1)
stock_qty = 0
count = 0
buildable_qty = prod_details.qty
for item in item_list:
count = count + 1
if item.build_qty >= (prod_details.qty - prod_details.produced_qty):
stock_qty = stock_qty + 1
elif buildable_qty >= item.build_qty:
buildable_qty = item.build_qty
if count == stock_qty:
build = "Y"
else:
build = "N"
row = frappe._dict({
"production_order": prod_order.name,
"status": prod_order.status,
"req_items": cint(count),
"instock": stock_qty,
"description": desc,
"bom_no": prod_details.bom_no,
"qty": prod_details.qty,
"buildable_qty": buildable_qty,
"ready_to_build": build
})
out.append(row)
for prod_item_details in frappe.db.get_values("Production Order Item",
{"parent": prod_details.name}, ["item_code", "source_warehouse"], as_dict=1):
item_list = frappe.db.sql("""SELECT
bom_item.item_code as item_code,
ifnull(ledger.actual_qty*bom.quantity/bom_item.stock_qty,0) as build_qty
FROM
`tabBOM` as bom, `tabBOM Item` AS bom_item
LEFT JOIN `tabBin` AS ledger
ON bom_item.item_code = ledger.item_code
AND ledger.warehouse = ifnull(%(warehouse)s,%(filterhouse)s)
WHERE
bom.name = bom_item.parent
and bom_item.item_code = %(item_code)s
and bom.name = %(bom)s
GROUP BY
bom_item.item_code""",
{"bom": prod_details.bom_no, "warehouse": prod_item_details.source_warehouse,
"filterhouse": filters.warehouse, "item_code": prod_item_details.item_code}, as_dict=1)
stock_qty = 0
count = 0
buildable_qty = prod_details.qty
for item in item_list:
count = count + 1
if item.build_qty >= (prod_details.qty - prod_details.produced_qty):
stock_qty = stock_qty + 1
elif buildable_qty >= item.build_qty:
buildable_qty = item.build_qty
if count == stock_qty:
build = "Y"
else:
build = "N"
row = frappe._dict({
"production_order": prod_details.name,
"status": prod_details.status,
"req_items": cint(count),
"instock": stock_qty,
"description": desc,
"source_warehouse": prod_item_details.source_warehouse,
"item_code": prod_item_details.item_code,
"bom_no": prod_details.bom_no,
"qty": prod_details.qty,
"buildable_qty": buildable_qty,
"ready_to_build": build
})
out.append(row)
return out
def get_production_orders():
out = frappe.get_all("Production Order", filters={"docstatus": 1, "status": ( "!=","Completed")}, fields=["name","status"], order_by='name')
out = frappe.get_all("Production Order", filters={"docstatus": 1, "status": ( "!=","Completed")},
fields=["name","status", "bom_no", "qty", "produced_qty"], order_by='name')
return out
def get_columns():
@@ -93,6 +97,18 @@ def get_columns():
"options": "",
"width": 230
}, {
"fieldname": "item_code",
"label": "Item Code",
"fieldtype": "Link",
"options": "Item",
"width": 110
},{
"fieldname": "source_warehouse",
"label": "Source Warehouse",
"fieldtype": "Link",
"options": "Warehouse",
"width": 110
},{
"fieldname": "qty",
"label": "Qty to Build",
"fieldtype": "Data",

View File

@@ -455,3 +455,12 @@ erpnext.patches.v9_0.add_healthcare_domain
erpnext.patches.v9_0.set_variant_item_description
erpnext.patches.v9_0.set_uoms_in_variant_field
erpnext.patches.v9_0.copy_old_fees_field_data
erpnext.patches.v9_0.set_pos_profile_name
erpnext.patches.v9_0.remove_non_existing_warehouse_from_stock_settings
execute:frappe.delete_doc_if_exists("DocType", "Program Fee")
erpnext.patches.v9_0.update_employee_loan_details
erpnext.patches.v9_2.delete_healthcare_domain_default_items
erpnext.patches.v9_2.rename_translated_domains_in_en
erpnext.patches.v9_2.repost_reserved_qty_for_production
erpnext.patches.v9_2.remove_company_from_patient
erpnext.patches.v9_2.set_item_name_in_production_order

View File

@@ -18,4 +18,6 @@ def execute():
and so.order_type = 'Sales'
and (so_item.delivery_date is null or so_item.delivery_date = ''
or so_item.delivery_date = '0000-00-00')
""")
and (so.delivery_date is not null and so.delivery_date != ''
and so.delivery_date != '0000-00-00')
""")

View File

@@ -5,6 +5,8 @@ from __future__ import unicode_literals
import frappe
def execute():
frappe.reload_doc("schools", "doctype", "fees")
if "total_amount" not in frappe.db.get_table_columns("Fees"):
return

View File

@@ -0,0 +1,7 @@
import frappe
def execute():
default_warehouse = frappe.db.get_value("Stock Settings", None, "default_warehouse")
if default_warehouse:
if not frappe.db.get_value("Warehouse", {"name": default_warehouse}):
frappe.db.set_value("Stock Settings", None, "default_warehouse", "")

View File

@@ -0,0 +1,24 @@
# Copyright (c) 2017, Frappe and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
def execute():
doctype = 'POS Profile'
frappe.reload_doctype(doctype)
for pos in frappe.get_all(doctype, filters={'disabled': 0}):
doc = frappe.get_doc(doctype, pos.name)
if not doc.user or doc.pos_profile_name: continue
try:
doc.pos_profile_name = doc.user + ' - ' + doc.company
doc.flags.ignore_validate = True
doc.flags.ignore_mandatory = True
doc.save()
frappe.rename_doc(doctype, doc.name, doc.pos_profile_name, force=True)
except frappe.LinkValidationError:
frappe.db.set_value("POS Profile", doc.name, 'disabled', 1)

View File

@@ -0,0 +1,24 @@
# Copyright (c) 2017, Frappe and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
def execute():
frappe.reload_doc('hr', 'doctype', 'salary_slip_loan')
frappe.reload_doc('hr', 'doctype', 'salary_slip')
for data in frappe.db.sql(""" select name,
start_date, end_date, total_loan_repayment
from
`tabSalary Slip`
where
docstatus < 2 and ifnull(total_loan_repayment, 0) > 0""", as_dict=1):
salary_slip = frappe.get_doc('Salary Slip', data.name)
salary_slip.set_loan_repayment()
if salary_slip.total_loan_repayment == data.total_loan_repayment:
for row in salary_slip.loans:
row.db_update()
salary_slip.db_update()

View File

View File

@@ -0,0 +1,16 @@
import frappe
from frappe.utils import getdate
def execute():
domain_settings = frappe.get_doc('Domain Settings')
active_domains = [d.domain for d in domain_settings.active_domains]
if "Healthcare" not in active_domains:
items = ["TTT", "MCH", "LDL", "GTT", "HDL", "BILT", "BILD", "BP", "BS"]
for item_code in items:
try:
item = frappe.db.get_value("Item", {"item_code": item_code}, ["name", "creation"], as_dict=1)
if item and getdate(item.creation) >= getdate("2017-11-10"):
frappe.delete_doc("Item", item.name)
except:
pass

View File

@@ -0,0 +1,6 @@
import frappe
def execute():
if frappe.db.exists("DocType", "Patient"):
if 'company' in frappe.db.get_table_columns("Patient"):
frappe.db.sql("alter table `tabPatient` drop column company")

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