Compare commits

..

117 Commits

Author SHA1 Message Date
gavin
49b0afccbd Merge pull request #21213 from gavindsouza/freeze-v10
chore(v10): pin python dependencies
2020-06-15 10:27:53 +05:30
Gavin D'souza
1183d3e1bc chore(travis): update and install setuptools and pip 2020-04-09 20:22:20 +05:30
Gavin D'souza
f876f4c2b2 chore: allow sudo in travis runs 2020-04-09 17:50:33 +05:30
Gavin D'souza
ac4a3057cf fix: travis add pip3 addon 2020-04-09 17:40:25 +05:30
Gavin D'souza
999216e727 fix: update easy install script usage 2020-04-09 15:17:41 +05:30
Gavin D'souza
a5fa29f256 chore: pin python dependencies 2020-04-09 10:44:34 +05:30
Deepesh Garg
1fddde0c0e fix: Account type in Handling Difference in Inventory account (#19678)
* fix: Account type in Handling Difference in Inventory account

* fix: Add Stock Adjustment account

* fix: Rename account to stock adjustment
2019-11-28 18:29:46 +05:30
Mangesh-Khairnar
e269aa9781 fix(bin): update requested qty in bin (#18314) 2019-07-15 14:07:50 +05:30
Aditya Hase
30be1181ea fix(error-report): Do not send error reports to support@erpnext.com (#17864) 2019-06-06 11:16:01 +05:30
Shivam Mishra
5a1b778cd2 Merge pull request #17793 from adityahase/remove-manifest-v10
perf: Remove MANIFEST.in
2019-05-29 15:31:19 +05:30
Aditya Hase
6dcc3a7596 perf: Remove MANIFEST.in
Faster pip install -e erpnext

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

https://github.com/frappe/frappe/pull/7360
2019-05-29 15:15:51 +05:30
Shivam Mishra
3657b2b0a4 fix: Task status fix (#17498) 2019-05-06 14:52:30 +05:30
Nabin Hait
cd701e3e6f Merge pull request #17149 from hrwX/gst_patch
fix(India): run patch for GST custom fields
2019-05-03 09:26:04 +05:30
Nabin Hait
55e54ef6a1 skip the patch for outside India 2019-05-02 21:56:44 +05:30
Nabin Hait
fb12805435 Merge pull request #17345 from deepeshgarg007/delivery_note_v10
fix: Make button not appearing in delivery note
2019-04-23 18:41:33 +05:30
deepeshgarg007
d21f1c0ce2 fix: Make button not appearing in delivery note 2019-04-23 17:56:05 +05:30
Saurabh
60b6f79349 Merge pull request #17303 from sahil28297/new_v10_site_sync
fix(site_sync): return more data in level
2019-04-22 12:01:35 +05:30
Sahil Khan
9366449cb4 fix: import iteritems 2019-04-22 11:07:18 +05:30
Sahil Khan
d12ede8510 fix: syntax error 2019-04-22 10:11:35 +05:30
Deepesh Garg
63f1eded95 fix: Datatype fix for balance in account currency (#17314) 2019-04-20 20:41:17 +05:30
Sahil Khan
a34f459065 fix: refactor level 2019-04-20 14:29:11 +05:30
Sahil Khan
ff1bd34e4c fix(site_sync): return more data in level 2019-04-19 16:36:40 +05:30
sahil28297
6e63de447a Merge pull request #17247 from frappe/revert-17227-v10_site_sync
Revert "feat(site_sync): return erpnext data"
2019-04-16 13:23:48 +05:30
sahil28297
d7ae52cd49 Revert "feat(site_sync): return erpnext data" 2019-04-16 13:23:16 +05:30
Nabin Hait
57646ec7de Merge pull request #17240 from hrwX/delivery_note_fix
fix(Delivery Note): Show get items even if note has been amended
2019-04-16 13:21:30 +05:30
Himanshu
d492db4ccb fix: let user delete the elements of items 2019-04-16 13:16:19 +05:30
Nabin Hait
16651241e8 Merge pull request #17227 from sahil28297/v10_site_sync
feat(site_sync): return erpnext data
2019-04-16 12:43:15 +05:30
Himanshu Warekar
e87e6d07ba fix: show get items even if note has been amended 2019-04-16 11:43:25 +05:30
Sahil Khan
a75973e9e5 feat(site_sync): return erpnext data 2019-04-14 18:45:31 +05:30
Himanshu Warekar
4802fc018b fix: run patch for gst 2019-04-05 17:01:19 +05:30
Nabin Hait
e012e2207a Merge pull request #17103 from hrwX/hsn_v10
fix(India): HSN Code
2019-04-05 15:52:01 +05:30
Himanshu Warekar
b7e0ae68ca fix: run gst patch 2019-04-04 11:17:15 +05:30
Himanshu Warekar
0e971f5088 Merge branch 'v10.x.x' of https://github.com/frappe/erpnext into hsn_v10 2019-04-04 11:16:44 +05:30
Nabin Hait
79936fa949 map supplier warehouse from PR to PI 2019-04-01 21:50:20 +05:30
Himanshu Warekar
203a712071 fix(India): HSN Code 2019-04-01 20:03:13 +05:30
Himanshu
c4bdefe666 fix(Leave Balance Report): return correct total number of leaves (#17009)
* fix: return correct total nuber of leaves

* Use ORM for query
2019-03-26 17:00:20 +05:30
Sagar Vora
898977bda8 Merge branch 'hotfix' 2019-01-29 17:10:19 +05:30
Sagar Vora
b32d9458b5 bumped to version 10.1.81 2019-01-29 17:30:19 +05:50
Nabin Hait
25cb13c0f8 Merge pull request #16508 from navdeepghai1/salary-slip-net-pay-fixes
fix(human resources): gross pay calculation issue
2019-01-29 12:08:11 +05:30
Nabin Hait
1c5d681f65 Merge pull request #16500 from scmmishra/v10-remove-docs
feat: [v10] Deprecate In App Help
2019-01-29 11:05:25 +05:30
Nabin Hait
8fae0b3017 Merge pull request #16242 from rohitwaghchaure/is_fixed_asset_checkbox_not_copied
[Fix] Is fixed asset checkbox not checked if user duplicate the existing invoice
2019-01-29 11:03:44 +05:30
Nabin Hait
57928a5382 Merge pull request #16468 from sagarvora/fix-scorecard
fix(buying): make supplier scorecard usable
2019-01-29 11:00:18 +05:30
Nabin Hait
b44b200e7c Merge branch 'hotfix' into fix-scorecard 2019-01-29 11:00:07 +05:30
Aditya Hase
9acb885e60 fix(sqli): Avoid SQL Injection with sender param (#16509) 2019-01-29 10:52:37 +05:30
Navdeep Ghai
ec570026e1 Merge branch 'hotfix' into salary-slip-net-pay-fixes 2019-01-29 09:12:37 +04:00
Nabin Hait
385e3bb284 Merge pull request #16446 from Zlash65/jv-fix
fix(accounts): wrong filters sent to fetch reference name in Journal Entry
2019-01-29 10:41:15 +05:30
navdeepghai1
92bb84aa70 Changed static precision(2) value to system setting currency_precision value 2019-01-28 16:54:58 +04:00
Sagar Vora
a1a946fcd6 Merge branch 'hotfix' into fix-scorecard 2019-01-28 12:20:55 +05:30
navdeepghai1
aac404a155 Fixed net_pay calculation issue 2019-01-28 10:42:16 +04:00
scmmishra
1b63fa1920 [fix] Formatting issues 2019-01-25 20:45:04 +05:30
scmmishra
e1f5d22a02 [fix] Code formatting, removed trailing spaces 2019-01-25 20:45:04 +05:30
scmmishra
000e216354 [feat] Added docsUrl variable to configure help_links 2019-01-25 20:44:45 +05:30
scmmishra
0be2aa33ac [fix] Links now redirect to erpnext.com 2019-01-25 20:41:54 +05:30
scmmishra
c6c1628c8a [feat] Modified help config 2019-01-25 20:41:54 +05:30
Nabin Hait
50e552321b Merge pull request #16363 from scmmishra/leave-application-naming
fix: Naming series not reflecting in leave application
2019-01-25 10:34:01 +05:30
Sagar Vora
e9778d9556 fix: do not use built-in "input", reload_doc 2019-01-23 17:13:31 +05:30
Sagar Vora
f51661b225 fix: allow operators, make weighting_function mandatory 2019-01-23 16:42:28 +05:30
Sagar Vora
9aeabce3d3 fix: trailing whitespace, duplication & more 2019-01-23 16:01:19 +05:30
Sagar Vora
57d7c837aa fix: supplier scorecard test 2019-01-23 14:26:35 +05:30
Sagar Vora
fb256d68ff Merge branch 'fix-supplier-scorecard' of /home/snv/Work/master_bench/apps/erpnext into fix-scorecard 2019-01-23 14:13:40 +05:30
Sagar Vora
037d0f8ba6 fix(buying): make supplier scorecard usable 2019-01-23 14:11:25 +05:30
Frappe Bot
d801437f5f Merge branch 'hotfix' 2019-01-23 08:08:53 +00:00
Frappe Bot
342854f6f2 bumped to version 10.1.80 2019-01-23 08:08:53 +00:00
Nabin Hait
06607fda4e fix: removed print statement 2019-01-23 12:15:48 +05:30
Nabin Hait
141c543f97 Update journal_entry.js 2019-01-23 12:14:55 +05:30
Aditya Hase
819a16d0f5 fix(dead-code): Remove .py files (#16462) 2019-01-23 07:57:08 +05:30
FinByz Tech Pvt. Ltd
237a871f17 fix: NoneType object has no attribute "gstin" (#16458)
* fix: NoneType object has no attribute "gstin"

* fix: handle NoneType values
2019-01-22 20:49:06 +05:30
Sagar Vora
33bc3f3309 Merge branch 'hotfix' 2019-01-22 18:15:44 +05:30
Sagar Vora
2a9a867f05 bumped to version 10.1.79 2019-01-22 18:35:44 +05:50
Sagar Vora
ecf6467799 fix(travis): Redis must be working for caching, so reverting (#16455) 2019-01-22 17:41:56 +05:30
Sagar Vora
8c8e4fd130 Merge branch 'hotfix' 2019-01-22 15:33:48 +05:30
Sagar Vora
1e61dd024b bumped to version 10.1.78 2019-01-22 15:53:48 +05:50
Zlash65
270c4c2a87 fix: push party filter only if applicable 2019-01-22 12:47:25 +05:30
Zlash65
c8d632ddff fix: add set query for payroll entry in JV 2019-01-22 12:46:13 +05:30
Faris Ansari
f523611e12 Merge branch 'hotfix' into leave-application-naming 2019-01-18 14:30:39 +05:30
Nabin Hait
7bea25a23a Merge pull request #16415 from ks093/ks093-shopping-cart-fixes
fix: Show stock validation message while placing order and Quotation series field fix in shopping cart settings.
2019-01-18 10:46:24 +05:30
ks093
61c781325d Fix to show low stock message.
In case of order being placed with stock quantity more than available, message showing stock available wasn't showing due to tuple unpacking not happening correctly.
2019-01-17 12:16:43 +05:30
ks093
1ed819bb10 Refresh quotation_series field to show series 2019-01-17 12:09:04 +05:30
Nabin Hait
c8ac825f0d Merge branch 'hotfix' into leave-application-naming 2019-01-16 17:54:35 +05:30
Nabin Hait
f0571ddf4b Merge pull request #16393 from diamorafaela/quotation-currency
fix: Quotation to Sales Order with different currency
2019-01-16 10:13:44 +05:30
Nabin Hait
d98315c41c Merge pull request #16402 from sagarvora/fix-patch-testing
fix(tests): change patch order, optimise Travis
2019-01-16 10:13:14 +05:30
Saurabh
529cc1ca51 bumped to version 10.1.77 2019-01-15 19:46:36 +06:00
Nabin Hait
d36bc5a9fd Merge pull request #16327 from nabinhait/group_warehouse_stock_reco
Fetch items based on group warehouse in Stock Reconciliation
2019-01-15 17:49:07 +05:30
Sagar Vora
876d868fa1 fix(tests): change patch order, optimise travis 2019-01-15 15:45:33 +05:30
NahuelOperto
9080221d46 fix: added test cases 2019-01-14 12:12:56 -03:00
Nabin Hait
d92024bb0f Merge branch 'hotfix' into leave-application-naming 2019-01-14 20:26:01 +05:30
Nabin Hait
acd7f73d57 Merge branch 'hotfix' into group_warehouse_stock_reco 2019-01-14 20:25:53 +05:30
Nabin Hait
55c672eefd Merge branch 'hotfix' into is_fixed_asset_checkbox_not_copied 2019-01-14 20:25:22 +05:30
Nabin Hait
910a744263 Merge pull request #16391 from nabinhait/cc_fix
fix: Travis fix for hotfix branch
2019-01-14 20:24:23 +05:30
Nabin Hait
4ed7cfc515 tests(cost-center-company): Validate cost center's company and revent tests 2019-01-14 17:14:39 +05:30
NahuelOperto
7facc34851 fix: removed filter from method validate 2019-01-11 10:46:38 -03:00
Nabin Hait
0d208851a4 Fix(stock-reco): Fixed codacy issues 2019-01-10 17:56:11 +05:30
Sagar Vora
f99e013ebc fix: gstin validation should work when there is no state (#16378) 2019-01-10 11:57:24 +05:30
Nabin Hait
6b466fe230 Merge pull request #16326 from hrwX/hotfix-gst-fix
fix: GSTIN validation
2019-01-10 11:23:42 +05:30
Sagar Vora
07cf4e8f5b fix: use division consistent with Python 3 & other changes 2019-01-10 11:14:58 +05:30
karthikeyan5
2825b929c1 fix(GSTIN Validation - india): added checksum validation for GSTIN 2019-01-09 19:15:10 +05:30
scmmishra
e2762df90b Fix: Naming series not reflecting in leave application 2019-01-08 17:38:28 +05:30
Sagar Vora
f5a00dc0c1 Merge branch 'hotfix' into is_fixed_asset_checkbox_not_copied 2019-01-07 15:45:33 +05:30
Sagar Vora
d40743a570 fix: 14th digit may not be zero 2019-01-07 13:38:43 +05:30
Himanshu
75ab042632 removed lowercase regex 2019-01-04 17:13:43 +05:30
Himanshu
547229fef1 PAN card validation in GST 2019-01-03 23:20:38 +05:30
Nabin Hait
47c9826b6f test(reco-warehouse): Get items for group warehouse 2019-01-03 15:24:59 +05:30
Himanshu
53c040f838 Gst number validation fix 2019-01-03 12:50:18 +05:30
Himanshu
a09a6e4020 Merge pull request #2 from frappe/hotfix
Hotfix
2019-01-03 12:47:03 +05:30
Nabin Hait
cacbdec565 Merge pull request #16283 from rohitwaghchaure/fix_not_able_to_delete_customer
[Fix] Not able to delete customer if contact is available
2018-12-31 11:55:24 +05:30
Nabin Hait
fcbe410c2f feat(stock-reco): Fetch items based on group warehouse 2018-12-28 16:31:05 +05:30
Frappe Bot
23ee3c6fbe Merge branch 'hotfix' 2018-12-26 11:09:34 +00:00
Frappe Bot
9a9c9c2ba3 bumped to version 10.1.76 2018-12-26 11:09:34 +00:00
Rohit Waghchaure
52a692ee08 [Fix] Not able to delete customer if contact is available 2018-12-26 02:34:13 +05:30
rohitwaghchaure
7ec5e80b70 [Fix] While making sales invoice from delivery note, system not remove the returned qty (#16141) 2018-12-24 14:55:31 +05:30
Navdeep Ghai
c4d38c0afc Fix the disappears of image bug after uploading and saving the employee (#16217)
* Fix image disappears of image after uploading and saving the employee

* Fix the codacy issue
2018-12-24 14:53:19 +05:30
Shreya Shah
91ddadeefa fix: add currency to options (#16199) 2018-12-24 14:25:12 +05:30
Shreya Shah
d2b9093ecc fix: Check if items exist (#16248) 2018-12-24 14:21:07 +05:30
Raffael Meyer
ed3561279d Update README.md (#16224) 2018-12-24 14:19:51 +05:30
Nabin Hait
e9a2d57357 Merge pull request #16249 from shreyashah115/error-fix-2
Purchase order validation sql error
2018-12-21 10:59:20 +05:30
shreyashah115@gmail.com
ba8c041206 fix: Check if items exist 2018-12-20 13:23:51 +05:30
Rohit Waghchaure
f6f503a1f6 [Fix] Is fixed asset checkbox not checked if user duplicate the existing invoice 2018-12-19 15:15:35 +05:30
68 changed files with 1993 additions and 1851 deletions

View File

@@ -1,5 +1,12 @@
language: python
dist: trusty
dist: xenial
addons:
apt:
packages:
- "python3"
- "python3-pip"
python:
- "2.7"
@@ -9,14 +16,13 @@ services:
install:
- pip install flake8==3.3.0
- flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics
- sudo rm /etc/apt/sources.list.d/docker.list
- sudo -H python3 -m pip install --upgrade setuptools pip
- sudo apt-get install hhvm && rm -rf /home/travis/.kiex/
- sudo apt-get purge -y mysql-common mysql-server mysql-client
- nvm install v7.10.0
- wget https://raw.githubusercontent.com/frappe/bench/master/playbooks/install.py
- sudo python install.py --develop --user travis --without-bench-setup
- sudo pip install -e ~/bench
- sudo python3 install.py --develop --user travis --without-bench-setup
- sudo python3 -m pip install -e ~/bench
- rm $TRAVIS_BUILD_DIR/.git/shallow
- bash $TRAVIS_BUILD_DIR/travis/bench_init.sh
@@ -31,7 +37,6 @@ before_script:
- bench get-app erpnext $TRAVIS_BUILD_DIR
- bench use test_site
- bench reinstall --yes
- bench build
- bench scheduler disable
- sed -i 's/9000/9001/g' sites/common_site_config.json
- bench start &

View File

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

View File

@@ -8,7 +8,7 @@ Includes: Accounting, Inventory, Manufacturing, CRM, Sales, Purchase, Project Ma
ERPNext is built on the [Frappé](https://github.com/frappe/frappe) Framework, a full-stack web app framework in Python & JavaScript.
- [User Guide](https://erpnext.org/docs/user)
- [User Guide](https://erpnext.com/docs/user)
- [Discussion Forum](https://discuss.erpnext.com/)
---

View File

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

View File

@@ -1,465 +1,466 @@
{
"country_code": "ae",
"name": "U.A.E - Chart of Accounts",
"country_code": "ae",
"name": "U.A.E - Chart of Accounts",
"tree": {
"Assets": {
"Current Assets": {
"Accounts Receivable": {
"Corporate Credit Cards": {
"account_type": "Receivable"
},
},
"Other Receivable": {
"Accrued Rebates Due from Suppliers": {
"account_type": "Receivable"
},
"Accured Income from Suppliers": {
},
"Accrued Income from Suppliers": {
"account_type": "Receivable"
},
},
"Other Debtors": {
"account_type": "Receivable"
},
},
"account_type": "Receivable"
},
},
"Post Dated Cheques Received": {
"account_type": "Receivable"
},
},
"Staff Receivable": {
"account_type": "Receivable"
},
},
"Trade Receivable": {
"account_type": "Receivable"
},
},
"Trade in Opening Fees": {
"account_type": "Receivable"
},
},
"account_type": "Receivable"
},
},
"Cash in Hand & Banks": {
"Banks": {
"Bank Margin On LC & LG": {},
"Banks Blocked Deposits": {},
"Banks Call Deposit Accounts": {},
"Bank Margin On LC & LG": {},
"Banks Blocked Deposits": {},
"Banks Call Deposit Accounts": {},
"Banks Current Accounts": {
"account_type": "Bank"
},
},
"account_type": "Bank"
},
},
"Cash in Hand": {
"Cash in Safe": {
"Main Safe": {
"account_type": "Cash"
},
},
"Main Safe - Foreign Currency": {
"account_type": "Cash"
}
},
},
"Petty Cash": {
"Petty Cash - Admininistration": {
"account_type": "Cash"
},
},
"Petty Cash - Others": {
"account_type": "Cash"
}
},
},
"account_type": "Cash"
},
},
"Cash in Transit": {
"Credit Cards": {
"Gateway Credit Cards": {
"account_type": "Bank"
},
},
"Manual Visa & Master Cards": {
"account_type": "Bank"
},
},
"PayPal Account": {
"account_type": "Bank"
},
},
"Visa & Master Credit Cards": {
"account_type": "Bank"
}
}
}
},
},
"Inventory": {
"Consigned Stock": {
"Handling Difference in Inventory": {
"account_type": "Stock Adjustment"
},
"Items Delivered to Customs on temprary Base": {}
},
"Handling Difference in Inventory": {},
"Items Delivered to Customs on temporary Base": {}
},
"Stock in Hand": {
"account_type": "Stock"
}
},
"Perliminary and Preoperating Expenses": {
},
"Preliminary and Preoperating Expenses": {
"Preoperating Expenses": {}
},
},
"Prepayments & Deposits": {
"Deposits": {
"Deposit - Office Rent": {},
"Deposit Others": {},
"Deposit to Immigration (Visa)": {},
"Deposit - Office Rent": {},
"Deposit Others": {},
"Deposit to Immigration (Visa)": {},
"Deposits - Customs": {}
},
},
"Prepaid Taxes": {
"Sales Taxes Receivables": {},
"Sales Taxes Receivables": {},
"Withholding Tax Receivables": {}
},
},
"Prepayments": {
"Other Prepayments": {},
"PrePaid Advertisement Expenses": {},
"Prepaid Bank Guarantee": {},
"Prepaid Consultancy Fees": {},
"Prepaid Employees Housing": {},
"Prepaid Finance charge for Loans": {},
"Prepaid Legal Fees": {},
"Prepaid License Fees": {},
"Prepaid Life Insurance": {},
"Prepaid Maintenance": {},
"Prepaid Medical Insurance": {},
"Prepaid Office Rent": {},
"Prepaid Other Insurance": {},
"Prepaid Schooling Fees": {},
"Prepaid Site Hosting Fees": {},
"Other Prepayments": {},
"PrePaid Advertisement Expenses": {},
"Prepaid Bank Guarantee": {},
"Prepaid Consultancy Fees": {},
"Prepaid Employees Housing": {},
"Prepaid Finance charge for Loans": {},
"Prepaid Legal Fees": {},
"Prepaid License Fees": {},
"Prepaid Life Insurance": {},
"Prepaid Maintenance": {},
"Prepaid Medical Insurance": {},
"Prepaid Office Rent": {},
"Prepaid Other Insurance": {},
"Prepaid Schooling Fees": {},
"Prepaid Site Hosting Fees": {},
"Prepaid Sponsorship Fees": {}
}
}
},
},
"Long Term Assets": {
"Fixed Assets": {
"Accumulated Depreciation": {
"Acc. Depreciation of Motor Vehicles": {
"account_type": "Accumulated Depreciation"
},
},
"Acc. Deprn.Computer Hardware & Software": {
"account_type": "Accumulated Depreciation"
},
},
"Acc.Deprn.of Furniture & Office Equipment": {
"account_type": "Accumulated Depreciation"
},
},
"Amortisation on Leasehold Improvement": {
"account_type": "Accumulated Depreciation"
},
},
"account_type": "Accumulated Depreciation"
},
},
"Fixed Assets (Cost Price)": {
"Computer Hardware & Software": {
"account_type": "Fixed Asset"
},
},
"Furniture and Equipment": {
"account_type": "Fixed Asset"
},
"Leasehold Improvement": {},
"Motor Vehicules": {
},
"Leasehold Improvement": {},
"Motor Vehicles": {
"account_type": "Fixed Asset"
},
"Work In Progrees": {},
},
"Work In Progress": {},
"account_type": "Fixed Asset"
}
},
},
"Intangible Assets": {
"Computer Card Renewal": {},
"Dispoal of Outlets": {},
"Computer Card Renewal": {},
"Disposal of Outlets": {},
"Registration of Trademarks": {}
},
"Intercompany Accounts": {},
},
"Intercompany Accounts": {},
"Investments": {
"Investments in Subsidiaries": {}
}
},
},
"root_type": "Asset"
},
},
"Closing And Temporary Accounts": {
"Closing Accounts": {
"Closing Account": {}
},
},
"root_type": "Liability"
},
},
"Expenses": {
"Commercial Expenses": {
"Consultancy Fees": {},
"Consultancy Fees": {},
"Provision for Doubtful Debts": {}
},
},
"Cost of Sale": {
"Cost Of Goods Sold": {
"Cost Of Goods Sold I/C Sales": {},
"Cost Of Goods Sold I/C Sales": {},
"Cost of Goods Sold in Trading": {
"account_type": "Cost of Goods Sold"
},
},
"account_type": "Cost of Goods Sold"
},
},
"Expenses Included In Valuation": {
"account_type": "Expenses Included In Valuation"
},
"Stock Adjustment": {
"account_type": "Stock Adjustment"
}
},
},
"Depreciation": {
"Depreciation & Amortization": {
"Amortization on Leasehold Improvement": {},
"Amortization on Leasehold Improvement": {},
"Depreciation Of Computer Hard & Soft": {
"account_type": "Depreciation"
},
},
"Depreciation Of Furniture & Office Equipment\n\t\t\t": {
"account_type": "Depreciation"
},
},
"Depreciation Of Motor Vehicles": {
"account_type": "Depreciation"
}
}
},
},
"Direct Expenses": {
"Financial Charges": {
"Air Miles Card Charges": {},
"Amex Credit Cards Charges": {},
"Bank Finance & Loan Charges": {},
"Credit Card Charges": {},
"Credit Card Swipe Charges": {},
"Air Miles Card Charges": {},
"Amex Credit Cards Charges": {},
"Bank Finance & Loan Charges": {},
"Credit Card Charges": {},
"Credit Card Swipe Charges": {},
"PayPal Charges": {}
}
},
},
"MISC Charges": {
"Other Charges": {
"Captial Loss": {
"Disposal of Business Branch": {},
"Loss On Fixed Assets Disposal": {},
"Capital Loss": {
"Disposal of Business Branch": {},
"Loss On Fixed Assets Disposal": {},
"Loss on Difference on Exchange": {}
},
},
"Other Non Operating Exp": {
"Other Non Operating Expenses": {}
},
},
"Previous Year Adjustments": {
"Previous Year Adjustments Account": {}
},
},
"Royalty Fees": {
"Royalty to Parent Co.": {}
},
},
"Tax / Zakat Expenses": {
"Income Tax": {
"account_type": "Tax"
},
"Zakat": {},
},
"Zakat": {},
"account_type": "Tax"
}
}
},
},
"Share Resources": {
"Share Resource Expenses Account": {}
},
},
"Store Operating Expenses": {
"Selling, General & Admin Expenses": {
"Advertising Expenses": {
"Other - Advertising Expenses": {}
},
},
"Bank & Finance Charges": {
"Other Bank Charges": {}
},
},
"Communications": {
"Courrier": {},
"Others - Communication": {},
"Telephone": {},
"Courier": {},
"Others - Communication": {},
"Telephone": {},
"Web Site Hosting Fees": {}
},
},
"Office & Various Expenses": {
"Cleaning": {},
"Convoyance Expenses": {},
"Gifts & Donations": {},
"Insurance": {},
"Kitchen and Buffet Expenses": {},
"Maintenance": {},
"Others - Office Various Expenses": {},
"Security & Guard": {},
"Stationary From Suppliers": {},
"Stationary Out Of Stock": {},
"Subscriptions": {},
"Training": {},
"Cleaning": {},
"Conveyance Expenses": {},
"Gifts & Donations": {},
"Insurance": {},
"Kitchen and Buffet Expenses": {},
"Maintenance": {},
"Others - Office Various Expenses": {},
"Security & Guard": {},
"Stationary From Suppliers": {},
"Stationary Out Of Stock": {},
"Subscriptions": {},
"Training": {},
"Vehicle Expenses": {}
},
},
"Personnel Cost": {
"Basic Salary": {},
"End Of Service Indemnity": {},
"Housing Allowance": {},
"Leave Salary": {},
"Leave Ticket": {},
"Life Insurance": {},
"Medical Insurance": {},
"Personnel Cost Others": {},
"Sales Commission": {},
"Staff School Allowances": {},
"Transportation Allowance": {},
"Uniform": {},
"Basic Salary": {},
"End Of Service Indemnity": {},
"Housing Allowance": {},
"Leave Salary": {},
"Leave Ticket": {},
"Life Insurance": {},
"Medical Insurance": {},
"Personnel Cost Others": {},
"Sales Commission": {},
"Staff School Allowances": {},
"Transportation Allowance": {},
"Uniform": {},
"Visa Expenses": {}
},
},
"Professional & Legal Fees": {
"Audit Fees": {},
"Legal fees": {},
"Others - Professional Fees": {},
"Sponsorship Fees": {},
"Audit Fees": {},
"Legal fees": {},
"Others - Professional Fees": {},
"Sponsorship Fees": {},
"Trade License Fees": {}
},
},
"Provision & Write Off": {
"Amortisation of Preoperating Expenses": {},
"Cash Shortage": {},
"Others - Provision & Write off": {},
"Write Off Inventory": {},
"Amortisation of Preoperating Expenses": {},
"Cash Shortage": {},
"Others - Provision & Write off": {},
"Write Off Inventory": {},
"Write Off Receivables & Payables": {}
},
},
"Rent Expenses": {
"Office Rent": {},
"Office Rent": {},
"Warehouse Rent": {}
},
},
"Travel Expenses": {
"Air tickets": {},
"Hotel": {},
"Meals": {},
"Others": {},
"Air tickets": {},
"Hotel": {},
"Meals": {},
"Others": {},
"Per Diem": {}
},
},
"Utilities": {
"Other Utility Cahrges": {},
"Other Utility Cahrges": {},
"Water & Electricity": {}
}
}
},
},
"root_type": "Expense"
},
},
"Liabilities": {
"Current Liabilities": {
"Accounts Payable": {
"Payables": {
"Advance Paybale to Suppliers": {
"account_type": "Payable"
},
},
"Consigned Payable": {
"account_type": "Payable"
},
},
"Other Payable": {
"account_type": "Payable"
},
},
"Post Dated Cheques Paid": {
"account_type": "Payable"
},
"Staff Payable": {},
},
"Staff Payable": {},
"Suppliers Price Protection": {
"account_type": "Payable"
},
},
"Trade Payable": {
"account_type": "Payable"
},
},
"account_type": "Payable"
}
},
},
"Accruals & Provisions": {
"Accruals": {
"Accrued Personnel Cost": {
"Accrued - Commissions": {},
"Accrued - Leave Salary": {},
"Accrued - Leave Tickets": {},
"Accrued - Salaries": {},
"Accrued Other Personnel Cost": {},
"Accrued Salaries Increment": {},
"Accrued - Commissions": {},
"Accrued - Leave Salary": {},
"Accrued - Leave Tickets": {},
"Accrued - Salaries": {},
"Accrued Other Personnel Cost": {},
"Accrued Salaries Increment": {},
"Accrued-Staff Bonus": {}
}
},
},
"Accrued Expenses": {
"Accrued Other Expenses": {
"Accrued - Audit Fees": {},
"Accrued - Office Rent": {},
"Accrued - Sponsorship": {},
"Accrued - Telephone": {},
"Accrued - Utilities": {},
"Accrued - Audit Fees": {},
"Accrued - Office Rent": {},
"Accrued - Sponsorship": {},
"Accrued - Telephone": {},
"Accrued - Utilities": {},
"Accrued Others": {}
}
},
},
"Other Current Liabilities": {
"Accrued Dubai Customs": {},
"Deferred income": {},
"Accrued Dubai Customs": {},
"Deferred income": {},
"Shipping & Handling": {}
},
},
"Provisions": {
"Tax Payables": {
"Income Tax Payable": {},
"Sales Tax Payable": {},
"Income Tax Payable": {},
"Sales Tax Payable": {},
"Withholding Tax Payable": {}
}
},
},
"Short Term Loan": {}
},
},
"Duties and Taxes": {
"account_type": "Tax",
"account_type": "Tax",
"is_group": 1
},
},
"Reservations & Credit Notes": {
"Credit Notes": {
"Credit Notes to Customers": {},
"Credit Notes to Customers": {},
"Reservations": {}
}
},
},
"Stock Liabilities": {
"Stock Received But Not Billed": {
"account_type": "Stock Received But Not Billed"
}
},
},
"Unearned Income": {}
},
},
"Long Term Liabilities": {
"Long Term Loans & Provisions": {}
},
},
"root_type": "Liability"
},
},
"Revenue": {
"Direct Revenue": {
"Other Direct Revenue": {
"Other Revenue - Operating": {
"Advertising Income": {},
"Branding Income": {},
"Early Setmt Margin from Suppliers": {},
"Marketing Rebate from Suppliers": {},
"Rebate from Suppliers": {},
"Service Income": {},
"Advertising Income": {},
"Branding Income": {},
"Early Setmt Margin from Suppliers": {},
"Marketing Rebate from Suppliers": {},
"Rebate from Suppliers": {},
"Service Income": {},
"Space Rental Income": {}
}
}
},
},
"Indirect Revenue": {
"Other Indirect Revenue": {
"Capital Gain": {},
"Excess In Till": {},
"Gain On Difference Of Exchange": {},
"Management Consultancy Fees": {},
"Capital Gain": {},
"Excess In Till": {},
"Gain On Difference Of Exchange": {},
"Management Consultancy Fees": {},
"Other Income": {}
},
},
"Other Revenue - Non Operating": {
"Interest Revenue": {},
"Interest from FD": {},
"Products Listing Fees from Suppliers": {},
"Interest Revenue": {},
"Interest from FD": {},
"Products Listing Fees from Suppliers": {},
"Trade Opening Fees from suppliers": {}
}
},
},
"Sales": {
"Sales from Other Regions": {
"Sales from Other Region": {}
},
},
"Sales of same region": {
"Management Consultancy Fees 1": {},
"Sales Account": {},
"Management Consultancy Fees 1": {},
"Sales Account": {},
"Sales of I/C": {}
}
},
},
"root_type": "Income"
},
},
"Share Holder Equity": {
"Capital": {
"Contributed Capital": {},
"Share Capital": {},
"Shareholders Current A/c": {},
"Sub Ordinated Loan": {},
"Contributed Capital": {},
"Share Capital": {},
"Shareholders Current A/c": {},
"Sub Ordinated Loan": {},
"Treasury Stocks": {}
},
},
"Retained Earnings": {
"Current Year Results": {},
"Dividends Paid": {},
"Current Year Results": {},
"Dividends Paid": {},
"Previous Years Results": {}
},
"account_type": "Equity",
},
"account_type": "Equity",
"root_type": "Equity"
}
}

View File

@@ -18,15 +18,14 @@ class GLEntry(Document):
self.flags.ignore_submit_comment = True
self.check_mandatory()
self.validate_and_set_fiscal_year()
self.pl_must_have_cost_center()
self.validate_cost_center()
if not self.flags.from_repost:
self.pl_must_have_cost_center()
self.check_pl_account()
self.validate_cost_center()
self.validate_party()
self.validate_currency()
def on_update_with_args(self, adv_adj, update_outstanding = 'Yes', from_repost=False):
if not from_repost:
self.validate_account_details(adv_adj)

View File

@@ -145,6 +145,13 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({
};
}
// payroll entry
if(jvd.reference_type==="Payroll Entry") {
return {
query: "erpnext.hr.doctype.payroll_entry.payroll_entry.get_payroll_entries_for_jv",
};
}
var out = {
filters: [
[jvd.reference_type, "docstatus", "=", 1]
@@ -167,10 +174,18 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({
out.filters.push([jvd.reference_type, "per_billed", "<", 100]);
}
if(jvd.party_type && jvd.party) {
out.filters.push([jvd.reference_type,
(jvd.reference_type.indexOf("Sales")===0 ? "customer" : "supplier"), "=", jvd.party]);
var party_field = "";
if(jvd.reference_type.indexOf("Sales")===0) {
var party_field = "customer";
} else if (jvd.reference_type.indexOf("Purchase")===0) {
var party_field = "supplier";
}
if (party_field) {
out.filters.push([jvd.reference_type, party_field, "=", jvd.party]);
}
}
return out;

View File

@@ -216,7 +216,7 @@ def get_accountwise_gle(filters, gl_entries, gle_map):
if gle.posting_date < from_date or cstr(gle.is_opening) == "Yes":
update_value_in_dict(gle_map[gle.account].totals, 'opening', gle)
update_value_in_dict(totals, 'opening', gle)
update_value_in_dict(gle_map[gle.account].totals, 'closing', gle)
update_value_in_dict(totals, 'closing', gle)
@@ -323,7 +323,7 @@ def get_columns(filters):
{
"label": _("Balance") + " (" + filters.account_currency + ")",
"fieldname": "balance_in_account_currency",
"fieldtype": "Data",
"fieldtype": "Float",
"width": 100
}
])

View File

@@ -49,7 +49,17 @@ class TestAsset(unittest.TestCase):
self.assertFalse(frappe.db.get_value("GL Entry",
{"voucher_type": "Purchase Invoice", "voucher_no": pi.name}))
def test_is_fixed_asset_set(self):
doc = frappe.new_doc('Purchase Invoice')
doc.supplier = '_Test Supplier'
doc.append('items', {
'item_code': 'Macbook Pro',
'qty': 1
})
doc.set_missing_values()
self.assertEquals(doc.items[0].is_fixed_asset, 1)
def test_schedule_for_straight_line_method(self):
asset = frappe.get_doc("Asset", "Macbook Pro 1")

View File

@@ -85,6 +85,7 @@ class PurchaseOrder(BuyingController):
frappe.msgprint(_("{0} currently has a {1} Supplier Scorecard standing, and Purchase Orders to this supplier should be issued with caution.").format(self.supplier, standing), title=_("Caution"), indicator='orange')
def validate_minimum_order_qty(self):
if not self.get("items"): return
items = list(set([d.item_code for d in self.get("items")]))
itemwise_min_order_qty = frappe._dict(frappe.db.sql("""select name, min_order_qty

View File

@@ -13,15 +13,23 @@ frappe.ui.form.on("Supplier Scorecard", {
},
onload: function(frm) {
if (frm.doc.__unsaved == 1) {
loadAllCriteria(frm);
loadAllStandings(frm);
}
},
refresh: function(frm) {
if (frm.dashboard.hasOwnProperty('heatmap')) {
frm.dashboard.heatmap.setLegend([0,20,40,60,80,101],["#991600","#169900"]);
}
load_criteria: function(frm) {
frappe.call({
method: "erpnext.buying.doctype.supplier_scorecard_criteria.supplier_scorecard_criteria.get_criteria_list",
callback: function(r) {
frm.set_value('criteria', []);
for (var i = 0; i < r.message.length; i++)
{
var row = frm.add_child("criteria");
row.criteria_name = r.message[i].name;
frm.script_manager.trigger("criteria_name", row.doctype, row.name);
}
refresh_field("criteria");
}
});
}
});
@@ -29,8 +37,8 @@ frappe.ui.form.on("Supplier Scorecard", {
frappe.ui.form.on("Supplier Scorecard Scoring Standing", {
standing_name: function(frm, cdt, cdn) {
if (frm.doc.standing_name != undefined) {
var d = frappe.get_doc(cdt, cdn);
var d = frappe.get_doc(cdt, cdn);
if (d.standing_name) {
return frm.call({
method: "erpnext.buying.doctype.supplier_scorecard_standing.supplier_scorecard_standing.get_scoring_standing",
child: d,
@@ -42,86 +50,29 @@ frappe.ui.form.on("Supplier Scorecard Scoring Standing", {
}
});
frappe.ui.form.on("Supplier Scorecard Scoring Variable", {
variable_label: function(frm, cdt, cdn) {
if (frm.doc.variable_label != undefined) {
var d = frappe.get_doc(cdt, cdn);
return frm.call({
method: "erpnext.buying.doctype.supplier_scorecard_variable.supplier_scorecard_variable.get_scoring_variable",
child: d,
args: {
variable_label: d.variable_label
}
});
}
}
});
frappe.ui.form.on("Supplier Scorecard Scoring Criteria", {
criteria_name: function(frm, cdt, cdn) {
if (frm.doc.criteria_name != undefined) {
var d = frappe.get_doc(cdt, cdn);
frm.call({
method: "erpnext.buying.doctype.supplier_scorecard_criteria.supplier_scorecard_criteria.get_variables",
var d = frappe.get_doc(cdt, cdn);
if (d.criteria_name) {
return frm.call({
method: "frappe.client.get",
args: {
criteria_name: d.criteria_name
fieldname: "weight",
doctype: "Supplier Scorecard Criteria",
filters: {name: d.criteria_name}
},
callback: function(r) {
for (var i = 0; i < r.message.length; i++)
{
var exists = false;
for (var j = 0; j < frm.doc.variables.length; j++)
{
if(!frm.doc.variables[j].hasOwnProperty("variable_label")) {
frm.get_field("variables").grid.grid_rows[j].remove();
}
else if(frm.doc.variables[j].variable_label === r.message[i]) {
exists = true;
}
}
if (!exists){
var new_row = frm.add_child("variables");
new_row.variable_label = r.message[i];
frm.script_manager.trigger("variable_label", new_row.doctype, new_row.name);
}
if(r.message){
d.weight = r.message.weight;
frm.refresh_field('criteria', 'weight');
}
refresh_field("variables");
}
});
return frm.call({
method: "erpnext.buying.doctype.supplier_scorecard_criteria.supplier_scorecard_criteria.get_scoring_criteria",
child: d,
args: {
criteria_name: d.criteria_name
}
});
}
}
});
var loadAllCriteria = function(frm) {
frappe.call({
method: "erpnext.buying.doctype.supplier_scorecard_criteria.supplier_scorecard_criteria.get_criteria_list",
callback: function(r) {
for (var j = 0; j < frm.doc.criteria.length; j++)
{
if(!frm.doc.criteria[j].hasOwnProperty("criteria_name")) {
frm.get_field("criteria").grid.grid_rows[j].remove();
}
}
for (var i = 0; i < r.message.length; i++)
{
var new_row = frm.add_child("criteria");
new_row.criteria_name = r.message[i].name;
frm.script_manager.trigger("criteria_name", new_row.doctype, new_row.name);
}
refresh_field("criteria");
}
});
};
var loadAllStandings = function(frm) {
frappe.call({
method: "erpnext.buying.doctype.supplier_scorecard_standing.supplier_scorecard_standing.get_standings_list",

View File

@@ -54,6 +54,7 @@ class SupplierScorecard(Document):
`tabSupplier Scorecard Period` scp
WHERE
scp.scorecard = %(sc)s
AND scp.docstatus = 1
ORDER BY
scp.end_date DESC""",
{"sc": self.name}, as_dict=1)
@@ -110,7 +111,8 @@ def get_timeline_data(doctype, name):
FROM
`tabSupplier Scorecard Period` sc
WHERE
sc.scorecard = %(scs)s""",
sc.scorecard = %(scs)s
AND sc.docstatus = 1""",
{"scs": scs.name}, as_dict=1)
for sc in scorecards:
@@ -162,6 +164,7 @@ def make_all_scorecards(docname):
`tabSupplier Scorecard Period` scp
WHERE
scp.scorecard = %(sc)s
AND scp.docstatus = 1
AND (
(scp.start_date > %(end_date)s
AND scp.end_date < %(start_date)s)
@@ -170,12 +173,12 @@ def make_all_scorecards(docname):
AND scp.end_date > %(start_date)s))
ORDER BY
scp.end_date DESC""",
{"sc": docname, "start_date": start_date, "end_date": end_date, "supplier": supplier}, as_dict=1)
{"sc": docname, "start_date": start_date, "end_date": end_date}, as_dict=1)
if len(scorecards) == 0:
period_card = make_supplier_scorecard(docname, None)
period_card.start_date = start_date
period_card.end_date = end_date
period_card.save()
period_card.submit()
scp_count = scp_count + 1
if start_date < first_start_date:
first_start_date = start_date

View File

@@ -21,12 +21,6 @@ class TestSupplierScorecard(unittest.TestCase):
d.weight = 0
self.assertRaises(frappe.ValidationError,my_doc.insert)
def test_missing_variable(self):
delete_test_scorecards()
my_doc = make_supplier_scorecard()
del my_doc.variables
self.assertRaises(frappe.ValidationError,my_doc.insert)
def make_supplier_scorecard():
my_doc = frappe.get_doc(valid_scorecard[0])
@@ -118,56 +112,6 @@ valid_scorecard = [
}
],
"prevent_pos":0,
"variables": [
{
"param_name":"cost_of_on_time_shipments",
"doctype":"Supplier Scorecard Scoring Variable",
"parenttype":"Supplier Scorecard",
"variable_label":"Cost of On Time Shipments",
"path":"get_cost_of_on_time_shipments",
"parentfield":"variables"
},
{
"param_name":"tot_cost_shipments",
"doctype":"Supplier Scorecard Scoring Variable",
"parenttype":"Supplier Scorecard",
"variable_label":"Total Cost of Shipments",
"path":"get_total_cost_of_shipments",
"parentfield":"variables"
},
{
"param_name":"tot_days_late",
"doctype":"Supplier Scorecard Scoring Variable",
"parenttype":"Supplier Scorecard",
"variable_label":"Total Days Late",
"path":"get_total_days_late",
"parentfield":"variables"
},
{
"param_name":"total_working_days",
"doctype":"Supplier Scorecard Scoring Variable",
"parenttype":"Supplier Scorecard",
"variable_label":"Total Working Days",
"path":"get_total_workdays",
"parentfield":"variables"
},
{
"param_name":"on_time_shipment_num",
"doctype":"Supplier Scorecard Scoring Variable",
"parenttype":"Supplier Scorecard",
"variable_label":"# of On Time Shipments",
"path":"get_on_time_shipments",
"parentfield":"variables"
},
{
"param_name":"total_shipments",
"doctype":"Supplier Scorecard Scoring Variable",
"parenttype":"Supplier Scorecard",
"variable_label":"Total Shipments",
"path":"get_total_shipments",
"parentfield":"variables"
}
],
"period":"Per Month",
"doctype":"Supplier Scorecard",
"warn_pos":0,
@@ -177,14 +121,12 @@ valid_scorecard = [
{
"weight":100.0,
"doctype":"Supplier Scorecard Scoring Criteria",
"formula":"(({cost_of_on_time_shipments} / {tot_cost_shipments}) if {tot_cost_shipments} > 0 else 1 )* 100 ",
"criteria_name":"Delivery",
"max_score":100.0,
"criteria_name":"Delivery"
}
],
"supplier":"_Test Supplier",
"name":"_Test Supplier",
"weighting_function":"{total_score} * max( 0, min ( 1 , (12 - {period_number}) / 12) )",
"weighting_function":"{total_score} * max( 0, min ( 1 , (12 - {period_number}) / 12) )"
}
]

View File

@@ -4,7 +4,7 @@
"allow_import": 0,
"allow_rename": 0,
"autoname": "field:criteria_name",
"beta": 1,
"beta": 0,
"creation": "2017-05-29 01:32:43.064891",
"custom": 0,
"docstatus": 0,
@@ -43,36 +43,6 @@
"set_only_once": 0,
"unique": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "weight",
"fieldtype": "Percent",
"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": "Criteria Weight",
"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,
@@ -87,7 +57,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": "Max Score",
"length": 0,
@@ -114,10 +84,10 @@
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"ignore_xss_filter": 1,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Criteria Formula",
"length": 0,
@@ -133,6 +103,36 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "weight",
"fieldtype": "Percent",
"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": "Criteria Weight",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"has_web_view": 0,
@@ -145,7 +145,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-07-17 10:30:47.458285",
"modified": "2019-01-22 10:47:00.000822",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Scorecard Criteria",

View File

@@ -30,21 +30,11 @@ class SupplierScorecardCriteria(Document):
for dummy2 in range(0, len(match.groups())):
test_formula = test_formula.replace('{' + match.group(1) + '}', "0")
test_formula = test_formula.replace('&lt;','<').replace('&gt;','>')
try:
frappe.safe_eval(test_formula, None, {'max':max, 'min': min})
except Exception:
frappe.throw(_("Error evaluating the criteria formula"))
@frappe.whitelist()
def get_scoring_criteria(criteria_name):
criteria = frappe.get_doc("Supplier Scorecard Criteria", criteria_name)
return criteria
@frappe.whitelist()
def get_criteria_list():
criteria = frappe.db.sql("""
@@ -56,7 +46,6 @@ def get_criteria_list():
return criteria
@frappe.whitelist()
def get_variables(criteria_name):
criteria = frappe.get_doc("Supplier Scorecard Criteria", criteria_name)
return _get_variables(criteria)
@@ -69,21 +58,16 @@ def _get_variables(criteria):
for dummy1, match in enumerate(mylist):
for dummy2 in range(0, len(match.groups())):
try:
#var = frappe.get_doc("Supplier Scorecard Variable", {'param_name' : d})
var = frappe.db.sql("""
SELECT
scv.name
scv.variable_label, scv.description, scv.param_name, scv.path
FROM
`tabSupplier Scorecard Variable` scv
WHERE
param_name=%(param)s""",
{'param':match.group(1)},)[0][0]
{'param':match.group(1)}, as_dict=1)[0]
my_variables.append(var)
except Exception:
# Ignore the ones where the variable can't be found
frappe.throw(_('Unable to find variable: ') + str(match.group(1)), InvalidFormulaVariable)
#pass
#frappe.msgprint(str(my_variables))
return my_variables

View File

@@ -6,9 +6,11 @@
frappe.ui.form.on("Supplier Scorecard Period", {
onload: function(frm) {
frm.get_field("variables").grid.toggle_display("value", true);
frm.get_field("criteria").grid.toggle_display("score", true);
let criteria_grid = frm.get_field("criteria").grid;
criteria_grid.toggle_enable("criteria_name", false);
criteria_grid.toggle_enable("weight", false);
criteria_grid.toggle_display("max_score", true);
criteria_grid.toggle_display("formula", true);
criteria_grid.toggle_display("score", true);
}
});

View File

@@ -4,7 +4,7 @@
"allow_import": 0,
"allow_rename": 0,
"autoname": "naming_series:",
"beta": 1,
"beta": 0,
"creation": "2017-05-30 00:38:18.773013",
"custom": 0,
"docstatus": 0,
@@ -281,7 +281,7 @@
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@@ -346,6 +346,36 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "amended_from",
"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": "Amended From",
"length": 0,
"no_copy": 1,
"options": "Supplier Scorecard Period",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"has_web_view": 0,
@@ -354,11 +384,11 @@
"idx": 0,
"image_view": 0,
"in_create": 1,
"is_submittable": 0,
"is_submittable": 1,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-07-12 07:33:26.130861",
"modified": "2019-01-23 13:58:26.137770",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Scorecard Period",
@@ -368,7 +398,7 @@
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"cancel": 1,
"create": 1,
"delete": 1,
"email": 1,
@@ -382,7 +412,7 @@
"role": "System Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"submit": 1,
"write": 1
}
],

View File

@@ -8,6 +8,7 @@ from frappe import throw, _
from frappe.model.document import Document
from frappe.model.mapper import get_mapped_doc
import erpnext.buying.doctype.supplier_scorecard_variable.supplier_scorecard_variable as variable_functions
from erpnext.buying.doctype.supplier_scorecard_criteria.supplier_scorecard_criteria import get_variables
class SupplierScorecardPeriod(Document):
@@ -28,7 +29,6 @@ class SupplierScorecardPeriod(Document):
def calculate_variables(self):
for var in self.variables:
if '.' in var.path:
method_to_call = import_string_path(var.path)
var.value = method_to_call(self)
@@ -39,29 +39,9 @@ class SupplierScorecardPeriod(Document):
def calculate_criteria(self):
#Get the criteria
for crit in self.criteria:
#me = ""
my_eval_statement = crit.formula.replace("\r", "").replace("\n", "")
#for let in my_eval_statement:
# me += let.encode('hex') + " "
#frappe.msgprint(me)
for var in self.variables:
if var.value:
if var.param_name in my_eval_statement:
my_eval_statement = my_eval_statement.replace('{' + var.param_name + '}', "{:.2f}".format(var.value))
else:
if var.param_name in my_eval_statement:
my_eval_statement = my_eval_statement.replace('{' + var.param_name + '}', '0.0')
#frappe.msgprint(my_eval_statement )
my_eval_statement = my_eval_statement.replace('&lt;','<').replace('&gt;','>')
try:
crit.score = min(crit.max_score, max( 0 ,frappe.safe_eval(my_eval_statement, None, {'max':max, 'min': min})))
crit.score = min(crit.max_score, max( 0 ,frappe.safe_eval(self.get_eval_statement(crit.formula), None, {'max':max, 'min': min})))
except Exception:
frappe.throw(_("Could not solve criteria score function for {0}. Make sure the formula is valid.".format(crit.criteria_name)),frappe.ValidationError)
crit.score = 0
@@ -73,26 +53,27 @@ class SupplierScorecardPeriod(Document):
self.total_score = myscore
def calculate_weighted_score(self, weighing_function):
my_eval_statement = weighing_function.replace("\r", "").replace("\n", "")
for var in self.variables:
if var.value:
if var.param_name in my_eval_statement:
my_eval_statement = my_eval_statement.replace('{' + var.param_name + '}', "{:.2f}".format(var.value))
else:
if var.param_name in my_eval_statement:
my_eval_statement = my_eval_statement.replace('{' + var.param_name + '}', '0.0')
my_eval_statement = my_eval_statement.replace('&lt;','<').replace('&gt;','>')
try:
weighed_score = frappe.safe_eval(my_eval_statement, None, {'max':max, 'min': min})
weighed_score = frappe.safe_eval(self.get_eval_statement(weighing_function), None, {'max':max, 'min': min})
except Exception:
frappe.throw(_("Could not solve weighted score function. Make sure the formula is valid."),frappe.ValidationError)
weighed_score = 0
return weighed_score
def get_eval_statement(self, formula):
my_eval_statement = formula.replace("\r", "").replace("\n", "")
for var in self.variables:
if var.value:
if var.param_name in my_eval_statement:
my_eval_statement = my_eval_statement.replace('{' + var.param_name + '}', "{:.2f}".format(var.value))
else:
if var.param_name in my_eval_statement:
my_eval_statement = my_eval_statement.replace('{' + var.param_name + '}', '0.0')
return my_eval_statement
def import_string_path(path):
components = path.split('.')
@@ -102,30 +83,28 @@ def import_string_path(path):
return mod
def post_process(source, target):
pass
@frappe.whitelist()
def make_supplier_scorecard(source_name, target_doc=None):
#def update_item(obj, target, source_parent):
# target.qty = flt(obj.qty) - flt(obj.received_qty)
# target.stock_qty = (flt(obj.qty) - flt(obj.received_qty)) * flt(obj.conversion_factor)
# target.amount = (flt(obj.qty) - flt(obj.received_qty)) * flt(obj.rate)
# target.base_amount = (flt(obj.qty) - flt(obj.received_qty)) * \
# flt(obj.rate) * flt(source_parent.conversion_rate)
def update_criteria_fields(obj, target, source_parent):
target.max_score, target.formula = frappe.db.get_value('Supplier Scorecard Criteria',
obj.criteria_name, ['max_score', 'formula'])
def post_process(source, target):
variables = []
for cr in target.criteria:
for var in get_variables(cr.criteria_name):
if var not in variables:
variables.append(var)
target.extend('variables', variables)
doc = get_mapped_doc("Supplier Scorecard", source_name, {
"Supplier Scorecard": {
"doctype": "Supplier Scorecard Period"
},
"Supplier Scorecard Scoring Variable": {
"doctype": "Supplier Scorecard Scoring Variable",
"add_if_empty": True
},
"Supplier Scorecard Scoring Constraint": {
"doctype": "Supplier Scorecard Scoring Constraint",
"add_if_empty": True
"Supplier Scorecard Scoring Criteria": {
"doctype": "Supplier Scorecard Scoring Criteria",
"postprocess": update_criteria_fields,
}
}, target_doc, post_process)

View File

@@ -1,280 +1,252 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 1,
"creation": "2017-05-29 01:32:17.988454",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2017-05-29 01:32:17.988454",
"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": 3,
"fieldname": "criteria_name",
"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": "Criteria Name",
"length": 0,
"no_copy": 0,
"options": "Supplier Scorecard Criteria",
"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,
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 5,
"fieldname": "criteria_name",
"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": "Criteria Name",
"length": 0,
"no_copy": 0,
"options": "Supplier Scorecard Criteria",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "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,
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 2,
"fieldname": "score",
"fieldtype": "Percent",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Score",
"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": 2,
"fieldname": "weight",
"fieldtype": "Percent",
"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": "Criteria Weight",
"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,
"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": "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,
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 2,
"fieldname": "weight",
"fieldtype": "Percent",
"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": "Criteria Weight",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "100",
"fieldname": "max_score",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Max Score",
"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,
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "100",
"fieldname": "max_score",
"fieldtype": "Float",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Max Score",
"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": "section_break_6",
"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,
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_6",
"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": "formula",
"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": "Criteria Formula",
"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,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "score",
"fieldtype": "Percent",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Score",
"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,
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "formula",
"fieldtype": "Small Text",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 1,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Criteria Formula",
"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
}
],
"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-07-12 07:33:41.532361",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Scorecard Scoring Criteria",
"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,
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2019-01-23 13:49:13.350095",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Scorecard Scoring Criteria",
"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

@@ -3,7 +3,7 @@
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 1,
"beta": 0,
"creation": "2017-05-29 01:36:22.697234",
"custom": 0,
"docstatus": 0,
@@ -473,7 +473,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2017-07-12 07:33:20.615684",
"modified": "2019-01-22 10:47:41.146704",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Scorecard Scoring Standing",

View File

@@ -3,7 +3,7 @@
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 1,
"beta": 0,
"creation": "2017-05-29 01:30:06.105240",
"custom": 0,
"docstatus": 0,
@@ -35,7 +35,7 @@
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
@@ -65,7 +65,37 @@
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 2,
"fieldname": "value",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Value",
"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,
@@ -73,36 +103,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "is_custom",
"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": "Custom?",
"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": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -111,7 +111,7 @@
"columns": 0,
"fieldname": "param_name",
"fieldtype": "Data",
"hidden": 0,
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
@@ -128,7 +128,7 @@
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@@ -141,7 +141,7 @@
"columns": 0,
"fieldname": "path",
"fieldtype": "Data",
"hidden": 0,
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
@@ -158,36 +158,6 @@
"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": 2,
"fieldname": "value",
"fieldtype": "Float",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Value",
"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,
@@ -204,7 +174,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2017-07-12 07:33:36.671502",
"modified": "2019-01-23 09:55:19.749828",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Scorecard Scoring Variable",

View File

@@ -4,7 +4,7 @@
"allow_import": 0,
"allow_rename": 0,
"autoname": "field:standing_name",
"beta": 1,
"beta": 0,
"creation": "2017-05-29 01:36:47.893639",
"custom": 0,
"docstatus": 0,
@@ -385,7 +385,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-07-12 07:33:16.560273",
"modified": "2019-01-22 10:47:49.195421",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Scorecard Standing",

View File

@@ -4,7 +4,7 @@
"allow_import": 0,
"allow_rename": 0,
"autoname": "field:variable_label",
"beta": 1,
"beta": 0,
"creation": "2017-05-29 01:30:34.688389",
"custom": 0,
"docstatus": 0,
@@ -101,7 +101,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"unique": 1
},
{
"allow_bulk_edit": 0,
@@ -203,7 +203,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-07-12 07:33:31.395262",
"modified": "2019-01-23 09:39:59.866398",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Scorecard Variable",

View File

@@ -27,13 +27,6 @@ class SupplierScorecardVariable(Document):
if not hasattr(sys.modules[__name__], self.path):
frappe.throw(_("Could not find path for " + self.path), VariablePathNotFound)
@frappe.whitelist()
def get_scoring_variable(variable_label):
variable = frappe.get_doc("Supplier Scorecard Variable", variable_label)
return variable
def get_total_workdays(scorecard):
""" Gets the number of days in this period"""
delta = getdate(scorecard.end_date) - getdate(scorecard.start_date)

View File

@@ -1 +1 @@
- [ERPNext Manual in German](http://erpnext.org/docs/user/manual/de/) contributed by [CWT Connector & Wire Technology GmbH](http://www.cwt-assembly.com/)
- [ERPNext Manual in German](http://erpnext.com/docs/user/manual/de/) contributed by [CWT Connector & Wire Technology GmbH](http://www.cwt-assembly.com/)

View File

@@ -218,6 +218,9 @@ class AccountsController(TransactionBase):
if stock_qty != len(get_serial_nos(item.get('serial_no'))):
item.set(fieldname, value)
if self.doctype in ["Purchase Invoice", "Sales Invoice"] and item.meta.get_field('is_fixed_asset'):
item.set('is_fixed_asset', ret.get('is_fixed_asset', 0))
if ret.get("pricing_rule"):
# if user changed the discount percentage then set user's discount percentage ?
item.set("discount_percentage", ret.get("discount_percentage"))

View File

@@ -462,7 +462,7 @@ class BuyingController(StockController):
update_last_purchase_rate(self, is_submit = 0)
def validate_schedule_date(self):
if not self.schedule_date:
if not self.schedule_date and self.get("items"):
self.schedule_date = min([d.schedule_date for d in self.get("items")])
if self.schedule_date:

View File

@@ -1,9 +0,0 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
class Lead(Document):
pass

View File

@@ -13,10 +13,6 @@ source_link = "https://github.com/frappe/erpnext"
develop_version = '10.x.x-develop'
error_report_email = "support@erpnext.com"
docs_app = "foundation"
app_include_js = "assets/js/erpnext.min.js"
app_include_css = "assets/css/erpnext.css"
web_include_js = "assets/js/erpnext-web.min.js"

View File

@@ -55,8 +55,8 @@ class Employee(NestedSet):
def validate_user_details(self):
data = frappe.db.get_value('User',
self.user_id, ['enabled', 'user_image'], as_dict=1)
self.image = data.get("user_image")
if data.get("user_image"):
self.image = data.get("user_image")
self.validate_for_enabled_user_id(data.get("enabled", 0))
self.validate_duplicate_user_id()
@@ -336,4 +336,4 @@ def get_children(doctype, parent=None, company=None, is_root=False, is_tree=Fals
.format(company=company, condition=condition), as_dict=1)
# return employee
return employee
return employee

View File

@@ -3,7 +3,7 @@
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "LAP/.#####",
"autoname": "naming_series:",
"beta": 0,
"creation": "2013-02-20 11:18:11",
"custom": 0,
@@ -796,7 +796,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 3,
"modified": "2017-06-13 14:28:52.426044",
"modified": "2019-01-08 17:35:10.795225",
"modified_by": "Administrator",
"module": "HR",
"name": "Leave Application",

View File

@@ -381,6 +381,19 @@ def get_leave_balance_on(employee, leave_type, date, allocation_records=None,
return flt(allocation.total_leaves_allocated) - flt(leaves_taken)
def get_total_allocated_leaves(employee, leave_type, date):
filters= {
'from_date': ['<=', date],
'to_date': ['>=', date],
'docstatus': 1,
'leave_type': leave_type,
'employee': employee
}
leave_allocation_records = frappe.db.get_all('Leave Allocation', filters=filters, fields=['total_leaves_allocated'])
return flt(leave_allocation_records[0]['total_leaves_allocated']) if leave_allocation_records else flt(0)
def get_approved_leaves_for_period(employee, leave_type, from_date, to_date):
leave_applications = frappe.db.sql("""
select employee, leave_type, from_date, to_date, total_leave_days

View File

@@ -525,3 +525,16 @@ def payroll_entry_has_bank_entries(name):
response['submitted'] = 1 if bank_entries else 0
return response
def get_payroll_entries_for_jv(doctype, txt, searchfield, start, page_len, filters):
return frappe.db.sql("""
select name from `tabPayroll Entry`
where `{key}` LIKE %(txt)s
and name not in
(select reference_name from `tabJournal Entry Account`
where reference_type="Payroll Entry")
order by name limit %(start)s, %(page_len)s"""
.format(key=searchfield), {
'txt': "%%%s%%" % frappe.db.escape(txt),
'start': start, 'page_len': page_len
})

View File

@@ -330,7 +330,7 @@ class SalarySlip(TransactionBase):
if frappe.db.get_value('Timesheet', data.time_sheet, 'status') == 'Payrolled':
frappe.throw(_("Salary Slip of employee {0} already created for time sheet {1}").format(self.employee, data.time_sheet))
def sum_components(self, component_type, total_field):
def sum_components(self, component_type, total_field, precision):
joining_date, relieving_date = frappe.db.get_value("Employee", self.employee,
["date_of_joining", "relieving_date"])
@@ -350,7 +350,7 @@ class SalarySlip(TransactionBase):
)):
d.amount = rounded(
(flt(d.default_amount) * flt(self.payment_days)
(flt(d.default_amount, precision) * flt(self.payment_days)
/ cint(self.total_working_days)), self.precision("amount", component_type)
)
@@ -360,19 +360,19 @@ class SalarySlip(TransactionBase):
elif not d.amount:
d.amount = d.default_amount
if not d.do_not_include_in_total:
self.set(total_field, self.get(total_field) + flt(d.amount))
self.set(total_field, self.get(total_field) + flt(d.amount, precision))
def calculate_net_pay(self):
if self.salary_structure:
self.calculate_component_amounts()
disable_rounded_total = cint(frappe.db.get_value("Global Defaults", None, "disable_rounded_total"))
precision = frappe.defaults.get_global_default("currency_precision")
self.total_deduction = 0
self.gross_pay = 0
self.sum_components('earnings', 'gross_pay')
self.sum_components('deductions', 'total_deduction')
self.sum_components('earnings', 'gross_pay', precision)
self.sum_components('deductions', 'total_deduction', precision)
self.set_loan_repayment()
@@ -473,4 +473,4 @@ def unlink_ref_doc_from_salary_slip(ref_no):
if linked_ss:
for ss in linked_ss:
ss_doc = frappe.get_doc("Salary Slip", ss)
frappe.db.set_value("Salary Slip", ss_doc.name, "journal_entry", "")
frappe.db.set_value("Salary Slip", ss_doc.name, "journal_entry", "")

View File

@@ -5,21 +5,21 @@ from __future__ import unicode_literals
import frappe
from frappe import _
from erpnext.hr.doctype.leave_application.leave_application \
import get_leave_allocation_records, get_leave_balance_on, get_approved_leaves_for_period
import get_leave_allocation_records, get_leave_balance_on, get_approved_leaves_for_period, get_total_allocated_leaves
def execute(filters=None):
leave_types = frappe.db.sql_list("select name from `tabLeave Type` order by name asc")
columns = get_columns(leave_types)
data = get_data(filters, leave_types)
return columns, data
def get_columns(leave_types):
columns = [
_("Employee") + ":Link/Employee:150",
_("Employee Name") + "::200",
_("Employee") + ":Link/Employee:150",
_("Employee Name") + "::200",
_("Department") +"::150"
]
@@ -27,18 +27,18 @@ def get_columns(leave_types):
columns.append(_(leave_type) + " " + _("Opening") + ":Float:160")
columns.append(_(leave_type) + " " + _("Taken") + ":Float:160")
columns.append(_(leave_type) + " " + _("Balance") + ":Float:160")
return columns
def get_data(filters, leave_types):
user = frappe.session.user
allocation_records_based_on_to_date = get_leave_allocation_records(filters.to_date)
allocation_records_based_on_from_date = get_leave_allocation_records(filters.from_date)
active_employees = frappe.get_all("Employee",
filters = { "status": "Active", "company": filters.company},
active_employees = frappe.get_all("Employee",
filters = { "status": "Active", "company": filters.company},
fields = ["name", "employee_name", "department", "user_id"])
data = []
for employee in active_employees:
leave_approvers = [l.leave_approver for l in frappe.db.sql("""select leave_approver from `tabEmployee Leave Approver` where parent = %s""",
@@ -52,15 +52,14 @@ def get_data(filters, leave_types):
filters.from_date, filters.to_date)
# opening balance
opening = get_leave_balance_on(employee.name, leave_type, filters.from_date,
allocation_records_based_on_from_date.get(employee.name, frappe._dict()))
opening = get_total_allocated_leaves(employee.name, leave_type, filters.to_date)
# closing balance
closing = get_leave_balance_on(employee.name, leave_type, filters.to_date,
allocation_records_based_on_to_date.get(employee.name, frappe._dict()))
row += [opening, leaves_taken, closing]
data.append(row)
return data

View File

@@ -1,8 +0,0 @@
import frappe
def set_required_items(production_order):
pass
def reserve_for_production(production_order):
'''Reserve pending raw materials for production'''
pass

View File

@@ -1,5 +1,6 @@
execute:import unidecode # new requirement
erpnext.patches.v8_0.move_perpetual_inventory_setting
erpnext.patches.v8_9.set_print_zero_amount_taxes
erpnext.patches.v10_0.rename_schools_to_education
erpnext.patches.v4_0.validate_v3_patch
erpnext.patches.v4_0.fix_employee_user_id
@@ -410,7 +411,7 @@ erpnext.patches.v8_0.save_system_settings
erpnext.patches.v8_1.delete_deprecated_reports
erpnext.patches.v9_0.remove_subscription_module
erpnext.patches.v8_7.make_subscription_from_recurring_data
erpnext.patches.v8_1.setup_gst_india #2017-06-27
erpnext.patches.v8_1.setup_gst_india #2019-04-04
execute:frappe.reload_doc('regional', 'doctype', 'gst_hsn_code')
erpnext.patches.v8_1.removed_roles_from_gst_report_non_indian_account
erpnext.patches.v8_1.gst_fixes #2017-07-06
@@ -442,7 +443,6 @@ erpnext.patches.v8_9.add_setup_progress_actions #08-09-2017 #26-09-2017 #22-11-2
erpnext.patches.v8_9.rename_company_sales_target_field
erpnext.patches.v8_8.set_bom_rate_as_per_uom
erpnext.patches.v8_8.add_new_fields_in_accounts_settings
erpnext.patches.v8_9.set_print_zero_amount_taxes
erpnext.patches.v8_9.set_default_customer_group
erpnext.patches.v8_9.remove_employee_from_salary_structure_parent
erpnext.patches.v8_9.delete_gst_doctypes_for_outside_india_accounts
@@ -498,6 +498,7 @@ erpnext.patches.v10_0.update_hub_connector_domain
erpnext.patches.v10_0.set_student_party_type
erpnext.patches.v10_0.update_project_in_sle
erpnext.patches.v10_0.fix_reserved_qty_for_sub_contract
erpnext.patches.v10_0.repost_requested_qty_for_non_stock_uom_items
erpnext.patches.v10_0.taxes_issue_with_pos
erpnext.patches.v10_0.set_qty_in_transactions_based_on_serial_no_input
erpnext.patches.v10_0.show_leaves_of_all_department_members_in_calendar
@@ -507,4 +508,6 @@ erpnext.patches.v10_0.set_discount_amount
erpnext.patches.v10_0.recalculate_gross_margin_for_project
erpnext.patches.v10_0.delete_hub_documents
erpnext.patches.v10_0.update_user_image_in_employee
erpnext.patches.v10_0.repost_gle_for_purchase_receipts_with_rejected_items
erpnext.patches.v10_0.repost_gle_for_purchase_receipts_with_rejected_items
erpnext.patches.v10_0.allow_operators_in_supplier_scorecard
erpnext.patches.v10_0.gst_hsn_fixes

View File

@@ -0,0 +1,23 @@
# Copyright (c) 2019, Frappe and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
def execute():
frappe.reload_doc('buying', 'doctype', 'supplier_scorecard_criteria')
frappe.reload_doc('buying', 'doctype', 'supplier_scorecard_scoring_criteria')
frappe.reload_doc('buying', 'doctype', 'supplier_scorecard')
for criteria in frappe.get_all('Supplier Scorecard Criteria', fields=['name', 'formula'], limit_page_length=None):
frappe.db.set_value('Supplier Scorecard Criteria', criteria.name,
'formula', criteria.formula.replace('&lt;','<').replace('&gt;','>'))
for criteria in frappe.get_all('Supplier Scorecard Scoring Criteria', fields=['name', 'formula'], limit_page_length=None):
if criteria.formula: # not mandatory
frappe.db.set_value('Supplier Scorecard Scoring Criteria', criteria.name,
'formula', criteria.formula.replace('&lt;','<').replace('&gt;','>'))
for sc in frappe.get_all('Supplier Scorecard', fields=['name', 'weighting_function'], limit_page_length=None):
frappe.db.set_value('Supplier Scorecard', sc.name, 'weighting_function',
sc.weighting_function.replace('&lt;','<').replace('&gt;','>'))

View File

@@ -0,0 +1,18 @@
import frappe
from erpnext.regional.india.setup import setup
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
def execute():
company = frappe.get_all('Company', filters = {'country': 'India'})
if not company:
return
hsn_sac_field = dict(fieldname='gst_hsn_code', label='HSN/SAC',
fieldtype='Data', options='item_code.gst_hsn_code', insert_after='description',
allow_on_submit=1, print_hide=1)
custom_fields = {
'Material Request Item': [hsn_sac_field]
}
create_custom_fields(custom_fields)

View File

@@ -0,0 +1,21 @@
# Copyright (c) 2019, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
def execute():
from erpnext.stock.stock_balance import update_bin_qty, get_indented_qty
count=0
for item_code, warehouse in frappe.db.sql("""select distinct item_code, warehouse
from `tabMaterial Request Item` where docstatus = 1 and stock_uom<>uom"""):
try:
count += 1
update_bin_qty(item_code, warehouse, {
"indented_qty": get_indented_qty(item_code, warehouse),
})
if count % 200 == 0:
frappe.db.commit()
except:
frappe.db.rollback()

View File

@@ -143,6 +143,13 @@ class Task(NestedSet):
self.update_nsm_model()
def update_status(self):
if self.status not in ('Cancelled', 'Closed') and self.exp_end_date:
from datetime import datetime
if self.exp_end_date < datetime.now().date():
self.db_set('status', 'Overdue')
self.update_project()
@frappe.whitelist()
def check_if_child_exists(name):
return frappe.db.sql("""select name from `tabTask`
@@ -168,10 +175,9 @@ def set_multiple_status(names, status):
task.save()
def set_tasks_as_overdue():
frappe.db.sql("""update tabTask set `status`='Overdue'
where exp_end_date is not null
and exp_end_date < CURDATE()
and `status` not in ('Closed', 'Cancelled')""")
tasks = frappe.get_all("Task", filters={'status':['not in',['Cancelled', 'Closed']]})
for task in tasks:
frappe.get_doc("Task", task.name).update_status()
@frappe.whitelist()
def get_children(doctype, parent, task=None, project=None, is_root=False):

View File

@@ -14,7 +14,7 @@ $(document).bind('toolbar_setup', function() {
$('.navbar-home').html('<img class="erpnext-icon" src="'+
frappe.urllib.get_base_url()+'/assets/erpnext/images/erp-icon.svg" />');
$('[data-link="docs"]').attr("href", "https://frappe.github.io/erpnext/")
$('[data-link="docs"]').attr("href", "https://erpnext.com/docs")
$('[data-link="issues"]').attr("href", "https://github.com/frappe/erpnext/issues")
@@ -23,7 +23,8 @@ $(document).bind('toolbar_setup', function() {
// additional help links for erpnext
var $help_menu = $('.dropdown-help ul .documentation-links');
$('<li><a data-link-type="forum" href="https://erpnext.com/docs/user/manual" \
target="_blank">'+__('Documentation')+'</a></li>').insertBefore($help_menu);
$('<li><a data-link-type="forum" href="https://discuss.erpnext.com" \
target="_blank">'+__('User Forum')+'</a></li>').insertBefore($help_menu);
$('<li><a href="https://gitter.im/frappe/erpnext" \

View File

@@ -1,528 +1,526 @@
frappe.provide('frappe.help.help_links');
const docsUrl = 'https://erpnext.com/docs/';
frappe.help.help_links['Form/Rename Tool'] = [
{ label: 'Bulk Rename', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/data/bulk-rename' },
{ label: 'Bulk Rename', url: docsUrl + 'user/manual/en/setting-up/data/bulk-rename' },
]
//Setup
frappe.help.help_links['List/User'] = [
{ label: 'New User', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/users-and-permissions/adding-users' },
{ label: 'Rename User', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/articles/rename-user' },
{ label: 'New User', url: docsUrl + 'user/manual/en/setting-up/users-and-permissions/adding-users' },
{ label: 'Rename User', url: docsUrl + 'user/manual/en/setting-up/articles/rename-user' },
]
frappe.help.help_links['permission-manager'] = [
{ label: 'Role Permissions Manager', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/users-and-permissions/role-based-permissions' },
{ label: 'Managing Perm Level in Permissions Manager', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/articles/managing-perm-level' },
{ label: 'User Permissions', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/users-and-permissions/user-permissions' },
{ label: 'Sharing', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/users-and-permissions/sharing' },
{ label: 'Password', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/articles/change-password' },
{ label: 'Role Permissions Manager', url: docsUrl + 'user/manual/en/setting-up/users-and-permissions/role-based-permissions' },
{ label: 'Managing Perm Level in Permissions Manager', url: docsUrl + 'user/manual/en/setting-up/articles/managing-perm-level' },
{ label: 'User Permissions', url: docsUrl + 'user/manual/en/setting-up/users-and-permissions/user-permissions' },
{ label: 'Sharing', url: docsUrl + 'user/manual/en/setting-up/users-and-permissions/sharing' },
{ label: 'Password', url: docsUrl + 'user/manual/en/setting-up/articles/change-password' },
]
frappe.help.help_links['Form/System Settings'] = [
{ label: 'Naming Series', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/settings/system-settings' },
{ label: 'Naming Series', url: docsUrl + 'user/manual/en/setting-up/settings/system-settings' },
]
frappe.help.help_links['data-import-tool'] = [
{ label: 'Importing and Exporting Data', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/data/data-import-tool' },
{ label: 'Overwriting Data from Data Import Tool', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/articles/overwriting-data-from-data-import-tool' },
{ label: 'Importing and Exporting Data', url: docsUrl + 'user/manual/en/setting-up/data/data-import-tool' },
{ label: 'Overwriting Data from Data Import Tool', url: docsUrl + 'user/manual/en/setting-up/articles/overwriting-data-from-data-import-tool' },
]
frappe.help.help_links['module_setup'] = [
{ label: 'Role Permissions Manager', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/users-and-permissions/role-based-permissions' },
{ label: 'Role Permissions Manager', url: docsUrl + 'user/manual/en/setting-up/users-and-permissions/role-based-permissions' },
]
frappe.help.help_links['Form/Naming Series'] = [
{ label: 'Naming Series', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/settings/naming-series' },
{ label: 'Setting the Current Value for Naming Series', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/articles/naming-series-current-value' },
{ label: 'Naming Series', url: docsUrl + 'user/manual/en/setting-up/settings/naming-series' },
{ label: 'Setting the Current Value for Naming Series', url: docsUrl + 'user/manual/en/setting-up/articles/naming-series-current-value' },
]
frappe.help.help_links['Form/Global Defaults'] = [
{ label: 'Global Settings', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/settings/global-defaults' },
{ label: 'Global Settings', url: docsUrl + 'user/manual/en/setting-up/settings/global-defaults' },
]
frappe.help.help_links['Form/Email Digest'] = [
{ label: 'Email Digest', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/email/email-digest' },
{ label: 'Email Digest', url: docsUrl + 'user/manual/en/setting-up/email/email-digest' },
]
frappe.help.help_links['List/Print Heading'] = [
{ label: 'Print Heading', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/print/print-headings' },
{ label: 'Print Heading', url: docsUrl + 'user/manual/en/setting-up/print/print-headings' },
]
frappe.help.help_links['List/Letter Head'] = [
{ label: 'Letter Head', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/print/letter-head' },
{ label: 'Letter Head', url: docsUrl + 'user/manual/en/setting-up/print/letter-head' },
]
frappe.help.help_links['List/Address Template'] = [
{ label: 'Address Template', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/print/address-template' },
{ label: 'Address Template', url: docsUrl + 'user/manual/en/setting-up/print/address-template' },
]
frappe.help.help_links['List/Terms and Conditions'] = [
{ label: 'Terms and Conditions', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/print/terms-and-conditions' },
{ label: 'Terms and Conditions', url: docsUrl + 'user/manual/en/setting-up/print/terms-and-conditions' },
]
frappe.help.help_links['List/Cheque Print Template'] = [
{ label: 'Cheque Print Template', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/print/cheque-print-template' },
{ label: 'Cheque Print Template', url: docsUrl + 'user/manual/en/setting-up/print/cheque-print-template' },
]
frappe.help.help_links['List/Email Account'] = [
{ label: 'Email Account', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/email/email-account' },
{ label: 'Email Account', url: docsUrl + 'user/manual/en/setting-up/email/email-account' },
]
frappe.help.help_links['List/Email Alert'] = [
{ label: 'Email Alert', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/email/email-alerts' },
frappe.help.help_links['List/Notification'] = [
{ label: 'Notification', url: docsUrl + 'user/manual/en/setting-up/email/notifications' },
]
frappe.help.help_links['Form/Email Alert'] = [
{ label: 'Email Alert', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/email/email-alerts' },
frappe.help.help_links['Form/Notification'] = [
{ label: 'Notification', url: docsUrl + 'user/manual/en/setting-up/email/notifications' },
]
frappe.help.help_links['List/Email Digest'] = [
{ label: 'Email Digest', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/email/email-digest' },
{ label: 'Email Digest', url: docsUrl + 'user/manual/en/setting-up/email/email-digest' },
]
frappe.help.help_links['List/Auto Email Report'] = [
{ label: 'Auto Email Reports', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/email/email-reports' },
{ label: 'Auto Email Reports', url: docsUrl + 'user/manual/en/setting-up/email/email-reports' },
]
frappe.help.help_links['Form/Print Settings'] = [
{ label: 'Print Settings', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/print/print-settings' },
{ label: 'Print Settings', url: docsUrl + 'user/manual/en/setting-up/print/print-settings' },
]
frappe.help.help_links['print-format-builder'] = [
{ label: 'Print Format Builder', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/print/print-settings' },
{ label: 'Print Format Builder', url: docsUrl + 'user/manual/en/setting-up/print/print-settings' },
]
frappe.help.help_links['List/Print Heading'] = [
{ label: 'Print Heading', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/print/print-headings' },
{ label: 'Print Heading', url: docsUrl + 'user/manual/en/setting-up/print/print-headings' },
]
//setup-integrations
frappe.help.help_links['Form/PayPal Settings'] = [
{ label: 'PayPal Settings', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/integrations/paypal-integration' },
{ label: 'PayPal Settings', url: docsUrl + 'user/manual/en/setting-up/integrations/paypal-integration' },
]
frappe.help.help_links['Form/Razorpay Settings'] = [
{ label: 'Razorpay Settings', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/integrations/razorpay-integration' },
{ label: 'Razorpay Settings', url: docsUrl + 'user/manual/en/setting-up/integrations/razorpay-integration' },
]
frappe.help.help_links['Form/Dropbox Settings'] = [
{ label: 'Dropbox Settings', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/integrations/dropbox-backup' },
{ label: 'Dropbox Settings', url: docsUrl + 'user/manual/en/setting-up/integrations/dropbox-backup' },
]
frappe.help.help_links['Form/LDAP Settings'] = [
{ label: 'LDAP Settings', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/integrations/ldap-integration' },
{ label: 'LDAP Settings', url: docsUrl + 'user/manual/en/setting-up/integrations/ldap-integration' },
]
frappe.help.help_links['Form/Stripe Settings'] = [
{ label: 'Stripe Settings', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/integrations/stripe-integration' },
{ label: 'Stripe Settings', url: docsUrl + 'user/manual/en/setting-up/integrations/stripe-integration' },
]
//Sales
frappe.help.help_links['Form/Quotation'] = [
{ label: 'Quotation', url: 'https://frappe.github.io/erpnext/user/manual/en/selling/quotation' },
{ label: 'Applying Discount', url: 'https://frappe.github.io/erpnext/user/manual/en/selling/articles/applying-discount' },
{ label: 'Sales Person', url: 'https://frappe.github.io/erpnext/user/manual/en/selling/articles/sales-persons-in-the-sales-transactions' },
{ label: 'Applying Margin', url: 'https://frappe.github.io/erpnext/user/manual/en/selling/articles/adding-margin' },
{ label: 'Quotation', url: docsUrl + 'user/manual/en/selling/quotation' },
{ label: 'Applying Discount', url: docsUrl + 'user/manual/en/selling/articles/applying-discount' },
{ label: 'Sales Person', url: docsUrl + 'user/manual/en/selling/articles/sales-persons-in-the-sales-transactions' },
{ label: 'Applying Margin', url: docsUrl + 'user/manual/en/selling/articles/adding-margin' },
]
frappe.help.help_links['List/Customer'] = [
{ label: 'Customer', url: 'https://frappe.github.io/erpnext/user/manual/en/CRM/customer' },
{ label: 'Credit Limit', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/credit-limit' },
{ label: 'Customer', url: docsUrl + 'user/manual/en/CRM/customer' },
{ label: 'Credit Limit', url: docsUrl + 'user/manual/en/accounts/credit-limit' },
]
frappe.help.help_links['Form/Customer'] = [
{ label: 'Customer', url: 'https://frappe.github.io/erpnext/user/manual/en/CRM/customer' },
{ label: 'Credit Limit', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/credit-limit' },
{ label: 'Customer', url: docsUrl + 'user/manual/en/CRM/customer' },
{ label: 'Credit Limit', url: docsUrl + 'user/manual/en/accounts/credit-limit' },
]
frappe.help.help_links['List/Sales Taxes and Charges Template'] = [
{ label: 'Setting Up Taxes', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/setting-up-taxes' },
{ label: 'Setting Up Taxes', url: docsUrl + 'user/manual/en/setting-up/setting-up-taxes' },
]
frappe.help.help_links['Form/Sales Taxes and Charges Template'] = [
{ label: 'Setting Up Taxes', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/setting-up-taxes' },
{ label: 'Setting Up Taxes', url: docsUrl + 'user/manual/en/setting-up/setting-up-taxes' },
]
frappe.help.help_links['List/Sales Order'] = [
{ label: 'Sales Order', url: 'https://frappe.github.io/erpnext/user/manual/en/selling/sales-order' },
{ label: 'Recurring Sales Order', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/recurring-orders-and-invoices' },
{ label: 'Applying Discount', url: 'https://frappe.github.io/erpnext/user/manual/en/selling/articles/applying-discount' },
{ label: 'Sales Order', url: docsUrl + 'user/manual/en/selling/sales-order' },
{ label: 'Recurring Sales Order', url: docsUrl + 'user/manual/en/accounts/recurring-orders-and-invoices' },
{ label: 'Applying Discount', url: docsUrl + 'user/manual/en/selling/articles/applying-discount' },
]
frappe.help.help_links['Form/Sales Order'] = [
{ label: 'Sales Order', url: 'https://frappe.github.io/erpnext/user/manual/en/selling/sales-order' },
{ label: 'Recurring Sales Order', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/recurring-orders-and-invoices' },
{ label: 'Applying Discount', url: 'https://frappe.github.io/erpnext/user/manual/en/selling/articles/applying-discount' },
{ label: 'Drop Shipping', url: 'https://frappe.github.io/erpnext/user/manual/en/selling/articles/drop-shipping' },
{ label: 'Sales Person', url: 'https://frappe.github.io/erpnext/user/manual/en/selling/articles/sales-persons-in-the-sales-transactions' },
{ label: 'Close Sales Order', url: 'https://frappe.github.io/erpnext/user/manual/en/selling/articles/close-sales-order' },
{ label: 'Applying Margin', url: 'https://frappe.github.io/erpnext/user/manual/en/selling/articles/adding-margin' },
{ label: 'Sales Order', url: docsUrl + 'user/manual/en/selling/sales-order' },
{ label: 'Recurring Sales Order', url: docsUrl + 'user/manual/en/accounts/recurring-orders-and-invoices' },
{ label: 'Applying Discount', url: docsUrl + 'user/manual/en/selling/articles/applying-discount' },
{ label: 'Drop Shipping', url: docsUrl + 'user/manual/en/selling/articles/drop-shipping' },
{ label: 'Sales Person', url: docsUrl + 'user/manual/en/selling/articles/sales-persons-in-the-sales-transactions' },
{ label: 'Close Sales Order', url: docsUrl + 'user/manual/en/selling/articles/close-sales-order' },
{ label: 'Applying Margin', url: docsUrl + 'user/manual/en/selling/articles/adding-margin' },
]
frappe.help.help_links['Form/Product Bundle'] = [
{ label: 'Product Bundle', url: 'https://frappe.github.io/erpnext/user/manual/en/selling/setup/product-bundle' },
{ label: 'Product Bundle', url: docsUrl + 'user/manual/en/selling/setup/product-bundle' },
]
frappe.help.help_links['Form/Selling Settings'] = [
{ label: 'Selling Settings', url: 'https://frappe.github.io/erpnext/user/manual/en/selling/setup/selling-settings' },
{ label: 'Selling Settings', url: docsUrl + 'user/manual/en/selling/setup/selling-settings' },
]
//Buying
frappe.help.help_links['List/Supplier'] = [
{ label: 'Supplier', url: 'https://frappe.github.io/erpnext/user/manual/en/buying/supplier' },
{ label: 'Supplier', url: docsUrl + 'user/manual/en/buying/supplier' },
]
frappe.help.help_links['Form/Supplier'] = [
{ label: 'Supplier', url: 'https://frappe.github.io/erpnext/user/manual/en/buying/supplier' },
{ label: 'Supplier', url: docsUrl + 'user/manual/en/buying/supplier' },
]
frappe.help.help_links['Form/Request for Quotation'] = [
{ label: 'Request for Quotation', url: 'https://frappe.github.io/erpnext/user/manual/en/buying/request-for-quotation' },
{ label: 'RFQ Video', url: 'https://frappe.github.io/erpnext/user/videos/learn/request-for-quotation.html' },
{ label: 'Request for Quotation', url: docsUrl + 'user/manual/en/buying/request-for-quotation' },
{ label: 'RFQ Video', url: docsUrl + 'user/videos/learn/request-for-quotation.html' },
]
frappe.help.help_links['Form/Supplier Quotation'] = [
{ label: 'Supplier Quotation', url: 'https://frappe.github.io/erpnext/user/manual/en/buying/supplier-quotation' },
{ label: 'Supplier Quotation', url: docsUrl + 'user/manual/en/buying/supplier-quotation' },
]
frappe.help.help_links['Form/Buying Settings'] = [
{ label: 'Buying Settings', url: 'https://frappe.github.io/erpnext/user/manual/en/buying/setup/buying-settings' },
{ label: 'Buying Settings', url: docsUrl + 'user/manual/en/buying/setup/buying-settings' },
]
frappe.help.help_links['List/Purchase Order'] = [
{ label: 'Purchase Order', url: 'https://frappe.github.io/erpnext/user/manual/en/buying/purchase-order' },
{ label: 'Recurring Purchase Order', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/recurring-orders-and-invoices' },
{ label: 'Purchase Order', url: docsUrl + 'user/manual/en/buying/purchase-order' },
{ label: 'Recurring Purchase Order', url: docsUrl + 'user/manual/en/accounts/recurring-orders-and-invoices' },
]
frappe.help.help_links['Form/Purchase Order'] = [
{ label: 'Purchase Order', url: 'https://frappe.github.io/erpnext/user/manual/en/buying/purchase-order' },
{ label: 'Item UoM', url: 'https://frappe.github.io/erpnext/user/manual/en/buying/articles/purchasing-in-different-unit' },
{ label: 'Supplier Item Code', url: 'https://frappe.github.io/erpnext/user/manual/en/buying/articles/maintaining-suppliers-part-no-in-item' },
{ label: 'Recurring Purchase Order', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/recurring-orders-and-invoices' },
{ label: 'Subcontracting', url: 'https://frappe.github.io/erpnext/user/manual/en/manufacturing/subcontracting' },
{ label: 'Purchase Order', url: docsUrl + 'user/manual/en/buying/purchase-order' },
{ label: 'Item UoM', url: docsUrl + 'user/manual/en/buying/articles/purchasing-in-different-unit' },
{ label: 'Supplier Item Code', url: docsUrl + 'user/manual/en/buying/articles/maintaining-suppliers-part-no-in-item' },
{ label: 'Recurring Purchase Order', url: docsUrl + 'user/manual/en/accounts/recurring-orders-and-invoices' },
{ label: 'Subcontracting', url: docsUrl + 'user/manual/en/manufacturing/subcontracting' },
]
frappe.help.help_links['List/Purchase Taxes and Charges Template'] = [
{ label: 'Setting Up Taxes', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/setting-up-taxes' },
{ label: 'Setting Up Taxes', url: docsUrl + 'user/manual/en/setting-up/setting-up-taxes' },
]
frappe.help.help_links['List/POS Profile'] = [
{ label: 'POS Profile', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/pos-setting' },
{ label: 'POS Profile', url: docsUrl + 'user/manual/en/setting-up/pos-setting' },
]
frappe.help.help_links['List/Price List'] = [
{ label: 'Price List', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/price-lists' },
{ label: 'Price List', url: docsUrl + 'user/manual/en/setting-up/price-lists' },
]
frappe.help.help_links['List/Authorization Rule'] = [
{ label: 'Authorization Rule', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/authorization-rule' },
{ label: 'Authorization Rule', url: docsUrl + 'user/manual/en/setting-up/authorization-rule' },
]
frappe.help.help_links['Form/SMS Settings'] = [
{ label: 'SMS Settings', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/sms-setting' },
{ label: 'SMS Settings', url: docsUrl + 'user/manual/en/setting-up/sms-setting' },
]
frappe.help.help_links['List/Stock Reconciliation'] = [
{ label: 'Stock Reconciliation', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/stock-reconciliation-for-non-serialized-item' },
{ label: 'Stock Reconciliation', url: docsUrl + 'user/manual/en/setting-up/stock-reconciliation-for-non-serialized-item' },
]
frappe.help.help_links['Tree/Territory'] = [
{ label: 'Territory', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/territory' },
{ label: 'Territory', url: docsUrl + 'user/manual/en/setting-up/territory' },
]
frappe.help.help_links['Form/Dropbox Backup'] = [
{ label: 'Dropbox Backup', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/third-party-backups' },
{ label: 'Setting Up Dropbox Backup', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/articles/setting-up-dropbox-backups' },
{ label: 'Dropbox Backup', url: docsUrl + 'user/manual/en/setting-up/third-party-backups' },
{ label: 'Setting Up Dropbox Backup', url: docsUrl + 'user/manual/en/setting-up/articles/setting-up-dropbox-backups' },
]
frappe.help.help_links['List/Workflow'] = [
{ label: 'Workflow', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/workflows' },
{ label: 'Workflow', url: docsUrl + 'user/manual/en/setting-up/workflows' },
]
frappe.help.help_links['List/Company'] = [
{ label: 'Company', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/company-setup' },
{ label: 'Managing Multiple Companies', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/articles/managing-multiple-companies' },
{ label: 'Delete All Related Transactions for a Company', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/articles/delete-a-company-and-all-related-transactions' },
{ label: 'Company', url: docsUrl + 'user/manual/en/setting-up/company-setup' },
{ label: 'Managing Multiple Companies', url: docsUrl + 'user/manual/en/setting-up/articles/managing-multiple-companies' },
{ label: 'Delete All Related Transactions for a Company', url: docsUrl + 'user/manual/en/setting-up/articles/delete-a-company-and-all-related-transactions' },
]
//Accounts
frappe.help.help_links['modules/Accounts'] = [
{ label: 'Introduction to Accounts', url: 'http://frappe.github.io/erpnext/user/manual/en/accounts/' },
{ label: 'Chart of Accounts', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/chart-of-accounts.html' },
{ label: 'Multi Currency Accounting', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/multi-currency-accounting' },
{ label: 'Introduction to Accounts', url: 'http://erpnext.com/docs/user/manual/en/accounts/' },
{ label: 'Chart of Accounts', url: docsUrl + 'user/manual/en/accounts/chart-of-accounts.html' },
{ label: 'Multi Currency Accounting', url: docsUrl + 'user/manual/en/accounts/multi-currency-accounting' },
]
frappe.help.help_links['Tree/Account'] = [
{ label: 'Chart of Accounts', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/chart-of-accounts' },
{ label: 'Managing Tree Mastes', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/articles/managing-tree-structure-masters' },
{ label: 'Chart of Accounts', url: docsUrl + 'user/manual/en/accounts/chart-of-accounts' },
{ label: 'Managing Tree Mastes', url: docsUrl + 'user/manual/en/setting-up/articles/managing-tree-structure-masters' },
]
frappe.help.help_links['Form/Sales Invoice'] = [
{ label: 'Sales Invoice', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/sales-invoice' },
{ label: 'Accounts Opening Balance', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/opening-accounts' },
{ label: 'Sales Return', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/sales-return' },
{ label: 'Recurring Sales Invoice', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/recurring-orders-and-invoices' },
{ label: 'Sales Invoice', url: docsUrl + 'user/manual/en/accounts/sales-invoice' },
{ label: 'Accounts Opening Balance', url: docsUrl + 'user/manual/en/accounts/opening-accounts' },
{ label: 'Sales Return', url: docsUrl + 'user/manual/en/stock/sales-return' },
{ label: 'Recurring Sales Invoice', url: docsUrl + 'user/manual/en/accounts/recurring-orders-and-invoices' },
]
frappe.help.help_links['List/Sales Invoice'] = [
{ label: 'Sales Invoice', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/sales-invoice' },
{ label: 'Accounts Opening Balance', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/opening-accounts' },
{ label: 'Sales Return', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/sales-return' },
{ label: 'Recurring Sales Invoice', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/recurring-orders-and-invoices' },
{ label: 'Sales Invoice', url: docsUrl + 'user/manual/en/accounts/sales-invoice' },
{ label: 'Accounts Opening Balance', url: docsUrl + 'user/manual/en/accounts/opening-accounts' },
{ label: 'Sales Return', url: docsUrl + 'user/manual/en/stock/sales-return' },
{ label: 'Recurring Sales Invoice', url: docsUrl + 'user/manual/en/accounts/recurring-orders-and-invoices' },
]
frappe.help.help_links['pos'] = [
{ label: 'Point of Sale Invoice', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/point-of-sale-pos-invoice' },
{ label: 'Point of Sale Invoice', url: docsUrl + 'user/manual/en/accounts/point-of-sale-pos-invoice' },
]
frappe.help.help_links['List/POS Profile'] = [
{ label: 'Point of Sale Profile', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/pos-setting' },
{ label: 'Point of Sale Profile', url: docsUrl + 'user/manual/en/setting-up/pos-setting' },
]
frappe.help.help_links['List/Purchase Invoice'] = [
{ label: 'Purchase Invoice', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/purchase-invoice' },
{ label: 'Accounts Opening Balance', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/opening-accounts' },
{ label: 'Recurring Purchase Invoice', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/recurring-orders-and-invoices' },
{ label: 'Purchase Invoice', url: docsUrl + 'user/manual/en/accounts/purchase-invoice' },
{ label: 'Accounts Opening Balance', url: docsUrl + 'user/manual/en/accounts/opening-accounts' },
{ label: 'Recurring Purchase Invoice', url: docsUrl + 'user/manual/en/accounts/recurring-orders-and-invoices' },
]
frappe.help.help_links['List/Journal Entry'] = [
{ label: 'Journal Entry', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/journal-entry' },
{ label: 'Advance Payment Entry', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/advance-payment-entry' },
{ label: 'Accounts Opening Balance', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/opening-accounts' },
{ label: 'Journal Entry', url: docsUrl + 'user/manual/en/accounts/journal-entry' },
{ label: 'Advance Payment Entry', url: docsUrl + 'user/manual/en/accounts/advance-payment-entry' },
{ label: 'Accounts Opening Balance', url: docsUrl + 'user/manual/en/accounts/opening-accounts' },
]
frappe.help.help_links['List/Payment Entry'] = [
{ label: 'Payment Entry', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/payment-entry' },
{ label: 'Payment Entry', url: docsUrl + 'user/manual/en/accounts/payment-entry' },
]
frappe.help.help_links['List/Payment Request'] = [
{ label: 'Payment Request', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/payment-request' },
{ label: 'Payment Request', url: docsUrl + 'user/manual/en/accounts/payment-request' },
]
frappe.help.help_links['List/Asset'] = [
{ label: 'Managing Fixed Assets', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/managing-fixed-assets' },
{ label: 'Managing Fixed Assets', url: docsUrl + 'user/manual/en/accounts/managing-fixed-assets' },
]
frappe.help.help_links['List/Asset Category'] = [
{ label: 'Asset Category', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/managing-fixed-assets' },
{ label: 'Asset Category', url: docsUrl + 'user/manual/en/accounts/managing-fixed-assets' },
]
frappe.help.help_links['Tree/Cost Center'] = [
{ label: 'Budgeting', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/budgeting' },
{ label: 'Budgeting', url: docsUrl + 'user/manual/en/accounts/budgeting' },
]
frappe.help.help_links['List/Item'] = [
{ label: 'Item', url: 'http://frappe.github.io/erpnext/user/manual/en/stock/item' },
{ label: 'Item Price', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/item/item-price' },
{ label: 'Barcode', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/articles/track-items-using-barcode' },
{ label: 'Item Wise Taxation', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/item-wise-taxation' },
{ label: 'Managing Fixed Assets', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/managing-fixed-assets' },
{ label: 'Item Codification', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/item/item-codification' },
{ label: 'Item Variants', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/item/item-variants' },
{ label: 'Item Valuation', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/item/item-valuation-fifo-and-moving-average' },
{ label: 'Item', url: 'http://erpnext.com/docs/user/manual/en/stock/item' },
{ label: 'Item Price', url: docsUrl + 'user/manual/en/stock/item/item-price' },
{ label: 'Barcode', url: docsUrl + 'user/manual/en/stock/articles/track-items-using-barcode' },
{ label: 'Item Wise Taxation', url: docsUrl + 'user/manual/en/accounts/item-wise-taxation' },
{ label: 'Managing Fixed Assets', url: docsUrl + 'user/manual/en/accounts/managing-fixed-assets' },
{ label: 'Item Codification', url: docsUrl + 'user/manual/en/stock/item/item-codification' },
{ label: 'Item Variants', url: docsUrl + 'user/manual/en/stock/item/item-variants' },
{ label: 'Item Valuation', url: docsUrl + 'user/manual/en/stock/item/item-valuation-fifo-and-moving-average' },
]
frappe.help.help_links['Form/Item'] = [
{ label: 'Item', url: 'http://frappe.github.io/erpnext/user/manual/en/stock/item' },
{ label: 'Item Price', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/item/item-price' },
{ label: 'Barcode', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/articles/track-items-using-barcode' },
{ label: 'Item Wise Taxation', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/item-wise-taxation' },
{ label: 'Managing Fixed Assets', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/managing-fixed-assets' },
{ label: 'Item Codification', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/item/item-codification' },
{ label: 'Item Variants', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/item/item-variants' },
{ label: 'Item Valuation', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/item/item-valuation-fifo-and-moving-average' },
{ label: 'Item', url: 'http://erpnext.com/docs/user/manual/en/stock/item' },
{ label: 'Item Price', url: docsUrl + 'user/manual/en/stock/item/item-price' },
{ label: 'Barcode', url: docsUrl + 'user/manual/en/stock/articles/track-items-using-barcode' },
{ label: 'Item Wise Taxation', url: docsUrl + 'user/manual/en/accounts/item-wise-taxation' },
{ label: 'Managing Fixed Assets', url: docsUrl + 'user/manual/en/accounts/managing-fixed-assets' },
{ label: 'Item Codification', url: docsUrl + 'user/manual/en/stock/item/item-codification' },
{ label: 'Item Variants', url: docsUrl + 'user/manual/en/stock/item/item-variants' },
{ label: 'Item Valuation', url: docsUrl + 'user/manual/en/stock/item/item-valuation-fifo-and-moving-average' },
]
frappe.help.help_links['List/Purchase Receipt'] = [
{ label: 'Purchase Receipt', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/purchase-receipt' },
{ label: 'Barcode', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/articles/track-items-using-barcode' },
{ label: 'Purchase Receipt', url: docsUrl + 'user/manual/en/stock/purchase-receipt' },
{ label: 'Barcode', url: docsUrl + 'user/manual/en/stock/articles/track-items-using-barcode' },
]
frappe.help.help_links['List/Delivery Note'] = [
{ label: 'Delivery Note', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/delivery-note' },
{ label: 'Barcode', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/articles/track-items-using-barcode' },
{ label: 'Sales Return', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/sales-return' },
{ label: 'Delivery Note', url: docsUrl + 'user/manual/en/stock/delivery-note' },
{ label: 'Barcode', url: docsUrl + 'user/manual/en/stock/articles/track-items-using-barcode' },
{ label: 'Sales Return', url: docsUrl + 'user/manual/en/stock/sales-return' },
]
frappe.help.help_links['Form/Delivery Note'] = [
{ label: 'Delivery Note', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/delivery-note' },
{ label: 'Sales Return', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/sales-return' },
{ label: 'Barcode', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/articles/track-items-using-barcode' },
{ label: 'Subcontracting', url: 'https://frappe.github.io/erpnext/user/manual/en/manufacturing/subcontracting' },
{ label: 'Delivery Note', url: docsUrl + 'user/manual/en/stock/delivery-note' },
{ label: 'Sales Return', url: docsUrl + 'user/manual/en/stock/sales-return' },
{ label: 'Barcode', url: docsUrl + 'user/manual/en/stock/articles/track-items-using-barcode' },
{ label: 'Subcontracting', url: docsUrl + 'user/manual/en/manufacturing/subcontracting' },
]
frappe.help.help_links['List/Installation Note'] = [
{ label: 'Installation Note', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/installation-note' },
{ label: 'Installation Note', url: docsUrl + 'user/manual/en/stock/installation-note' },
]
frappe.help.help_links['Tree'] = [
{ label: 'Managing Tree Structure Masters', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/articles/managing-tree-structure-masters' },
{ label: 'Managing Tree Structure Masters', url: docsUrl + 'user/manual/en/setting-up/articles/managing-tree-structure-masters' },
]
frappe.help.help_links['List/Budget'] = [
{ label: 'Budgeting', url: 'https://frappe.github.io/erpnext/user/manual/en/accounts/budgeting' },
{ label: 'Budgeting', url: docsUrl + 'user/manual/en/accounts/budgeting' },
]
//Stock
frappe.help.help_links['List/Material Request'] = [
{ label: 'Material Request', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/material-request' },
{ label: 'Auto-creation of Material Request', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/articles/auto-creation-of-material-request' },
{ label: 'Material Request', url: docsUrl + 'user/manual/en/stock/material-request' },
{ label: 'Auto-creation of Material Request', url: docsUrl + 'user/manual/en/stock/articles/auto-creation-of-material-request' },
]
frappe.help.help_links['Form/Material Request'] = [
{ label: 'Material Request', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/material-request' },
{ label: 'Auto-creation of Material Request', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/articles/auto-creation-of-material-request' },
{ label: 'Material Request', url: docsUrl + 'user/manual/en/stock/material-request' },
{ label: 'Auto-creation of Material Request', url: docsUrl + 'user/manual/en/stock/articles/auto-creation-of-material-request' },
]
frappe.help.help_links['Form/Stock Entry'] = [
{ label: 'Stock Entry', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/stock-entry' },
{ label: 'Stock Entry Types', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/articles/stock-entry-purpose' },
{ label: 'Repack Entry', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/articles/repack-entry' },
{ label: 'Opening Stock', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/opening-stock' },
{ label: 'Subcontracting', url: 'https://frappe.github.io/erpnext/user/manual/en/manufacturing/subcontracting' },
{ label: 'Stock Entry', url: docsUrl + 'user/manual/en/stock/stock-entry' },
{ label: 'Stock Entry Types', url: docsUrl + 'user/manual/en/stock/articles/stock-entry-purpose' },
{ label: 'Repack Entry', url: docsUrl + 'user/manual/en/stock/articles/repack-entry' },
{ label: 'Opening Stock', url: docsUrl + 'user/manual/en/stock/opening-stock' },
{ label: 'Subcontracting', url: docsUrl + 'user/manual/en/manufacturing/subcontracting' },
]
frappe.help.help_links['List/Stock Entry'] = [
{ label: 'Stock Entry', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/stock-entry' },
{ label: 'Stock Entry', url: docsUrl + 'user/manual/en/stock/stock-entry' },
]
frappe.help.help_links['Tree/Warehouse'] = [
{ label: 'Warehouse', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/warehouse' },
{ label: 'Warehouse', url: docsUrl + 'user/manual/en/stock/warehouse' },
]
frappe.help.help_links['List/Serial No'] = [
{ label: 'Serial No', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/serial-no' },
{ label: 'Serial No', url: docsUrl + 'user/manual/en/stock/serial-no' },
]
frappe.help.help_links['Form/Serial No'] = [
{ label: 'Serial No', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/serial-no' },
{ label: 'Serial No', url: docsUrl + 'user/manual/en/stock/serial-no' },
]
frappe.help.help_links['Form/Batch'] = [
{ label: 'Batch', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/batch' },
{ label: 'Batch', url: docsUrl + 'user/manual/en/stock/batch' },
]
frappe.help.help_links['Form/Packing Slip'] = [
{ label: 'Packing Slip', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/tools/packing-slip' },
{ label: 'Packing Slip', url: docsUrl + 'user/manual/en/stock/tools/packing-slip' },
]
frappe.help.help_links['Form/Quality Inspection'] = [
{ label: 'Quality Inspection', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/tools/quality-inspection' },
{ label: 'Quality Inspection', url: docsUrl + 'user/manual/en/stock/tools/quality-inspection' },
]
frappe.help.help_links['Form/Landed Cost Voucher'] = [
{ label: 'Landed Cost Voucher', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/tools/landed-cost-voucher' },
{ label: 'Landed Cost Voucher', url: docsUrl + 'user/manual/en/stock/tools/landed-cost-voucher' },
]
frappe.help.help_links['Tree/Item Group'] = [
{ label: 'Item Group', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/setup/item-group' },
{ label: 'Item Group', url: docsUrl + 'user/manual/en/stock/setup/item-group' },
]
frappe.help.help_links['Form/Item Attribute'] = [
{ label: 'Item Attribute', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/setup/item-attribute' },
{ label: 'Item Attribute', url: docsUrl + 'user/manual/en/stock/setup/item-attribute' },
]
frappe.help.help_links['Form/UOM'] = [
{ label: 'Fractions in UOM', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/articles/managing-fractions-in-uom' },
{ label: 'Fractions in UOM', url: docsUrl + 'user/manual/en/stock/articles/managing-fractions-in-uom' },
]
frappe.help.help_links['Form/Stock Reconciliation'] = [
{ label: 'Opening Stock Entry', url: 'https://frappe.github.io/erpnext/user/manual/en/stock/opening-stock' },
{ label: 'Opening Stock Entry', url: docsUrl + 'user/manual/en/stock/opening-stock' },
]
//CRM
frappe.help.help_links['Form/Lead'] = [
{ label: 'Lead', url: 'https://frappe.github.io/erpnext/user/manual/en/CRM/lead' },
{ label: 'Lead', url: docsUrl + 'user/manual/en/CRM/lead' },
]
frappe.help.help_links['Form/Opportunity'] = [
{ label: 'Opportunity', url: 'https://frappe.github.io/erpnext/user/manual/en/CRM/opportunity' },
{ label: 'Opportunity', url: docsUrl + 'user/manual/en/CRM/opportunity' },
]
frappe.help.help_links['Form/Address'] = [
{ label: 'Address', url: 'https://frappe.github.io/erpnext/user/manual/en/CRM/contact' },
{ label: 'Address', url: docsUrl + 'user/manual/en/CRM/contact' },
]
frappe.help.help_links['Form/Contact'] = [
{ label: 'Contact', url: 'https://frappe.github.io/erpnext/user/manual/en/CRM/contact' },
{ label: 'Contact', url: docsUrl + 'user/manual/en/CRM/contact' },
]
frappe.help.help_links['Form/Newsletter'] = [
{ label: 'Newsletter', url: 'https://frappe.github.io/erpnext/user/manual/en/CRM/newsletter' },
{ label: 'Newsletter', url: docsUrl + 'user/manual/en/CRM/newsletter' },
]
frappe.help.help_links['Form/Campaign'] = [
{ label: 'Campaign', url: 'https://frappe.github.io/erpnext/user/manual/en/CRM/setup/campaign' },
{ label: 'Campaign', url: docsUrl + 'user/manual/en/CRM/setup/campaign' },
]
frappe.help.help_links['Tree/Sales Person'] = [
{ label: 'Sales Person', url: 'https://frappe.github.io/erpnext/user/manual/en/CRM/setup/sales-person' },
{ label: 'Sales Person', url: docsUrl + 'user/manual/en/CRM/setup/sales-person' },
]
frappe.help.help_links['Form/Sales Person'] = [
{ label: 'Sales Person Target', url: 'https://frappe.github.io/erpnext/user/manual/en/selling/setup/sales-person-target-allocation' },
{ label: 'Sales Person Target', url: docsUrl + 'user/manual/en/selling/setup/sales-person-target-allocation' },
]
//Support
frappe.help.help_links['List/Feedback Trigger'] = [
{ label: 'Feedback Trigger', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/feedback/setting-up-feedback' },
{ label: 'Feedback Trigger', url: docsUrl + 'user/manual/en/setting-up/feedback/setting-up-feedback' },
]
frappe.help.help_links['List/Feedback Request'] = [
{ label: 'Feedback Request', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/feedback/submit-feedback' },
{ label: 'Feedback Request', url: docsUrl + 'user/manual/en/setting-up/feedback/submit-feedback' },
]
frappe.help.help_links['List/Feedback Request'] = [
{ label: 'Feedback Request', url: 'https://frappe.github.io/erpnext/user/manual/en/setting-up/feedback/submit-feedback' },
{ label: 'Feedback Request', url: docsUrl + 'user/manual/en/setting-up/feedback/submit-feedback' },
]
//Manufacturing
frappe.help.help_links['Form/BOM'] = [
{ label: 'Bill of Material', url: 'https://frappe.github.io/erpnext/user/manual/en/manufacturing/bill-of-materials' },
{ label: 'Nested BOM Structure', url: 'https://frappe.github.io/erpnext/user/manual/en/manufacturing/articles/nested-bom-structure' },
{ label: 'Bill of Material', url: docsUrl + 'user/manual/en/manufacturing/bill-of-materials' },
{ label: 'Nested BOM Structure', url: docsUrl + 'user/manual/en/manufacturing/articles/nested-bom-structure' },
]
frappe.help.help_links['Form/Production Order'] = [
{ label: 'Production Order', url: 'https://frappe.github.io/erpnext/user/manual/en/manufacturing/production-order' },
frappe.help.help_links['Form/Work Order'] = [
{ label: 'Work Order', url: docsUrl + 'user/manual/en/manufacturing/work-order' },
]
frappe.help.help_links['Form/Workstation'] = [
{ label: 'Workstation', url: 'https://frappe.github.io/erpnext/user/manual/en/manufacturing/workstation' },
{ label: 'Workstation', url: docsUrl + 'user/manual/en/manufacturing/workstation' },
]
frappe.help.help_links['Form/Operation'] = [
{ label: 'Operation', url: 'https://frappe.github.io/erpnext/user/manual/en/manufacturing/operation' },
]
frappe.help.help_links['Form/Production Planning Tool'] = [
{ label: 'Production Planning Tool', url: 'https://frappe.github.io/erpnext/user/manual/en/manufacturing/tools/production-planning-tool' },
{ label: 'Operation', url: docsUrl + 'user/manual/en/manufacturing/operation' },
]
frappe.help.help_links['Form/BOM Update Tool'] = [
{ label: 'BOM Update Tool', url: 'https://frappe.github.io/erpnext/user/manual/en/manufacturing/tools/bom-update-tool' },
{ label: 'BOM Update Tool', url: docsUrl + 'user/manual/en/manufacturing/tools/bom-update-tool' },
]
//Customize
frappe.help.help_links['Form/Customize Form'] = [
{ label: 'Custom Field', url: 'https://frappe.github.io/erpnext/user/manual/en/customize-erpnext/custom-field' },
{ label: 'Customize Field', url: 'https://frappe.github.io/erpnext/user/manual/en/customize-erpnext/customize-form' },
{ label: 'Custom Field', url: docsUrl + 'user/manual/en/customize-erpnext/custom-field' },
{ label: 'Customize Field', url: docsUrl + 'user/manual/en/customize-erpnext/customize-form' },
]
frappe.help.help_links['Form/Custom Field'] = [
{ label: 'Custom Field', url: 'https://frappe.github.io/erpnext/user/manual/en/customize-erpnext/custom-field' },
{ label: 'Custom Field', url: docsUrl + 'user/manual/en/customize-erpnext/custom-field' },
]
frappe.help.help_links['Form/Custom Field'] = [
{ label: 'Custom Field', url: 'https://frappe.github.io/erpnext/user/manual/en/customize-erpnext/custom-field' },
{ label: 'Custom Field', url: docsUrl + 'user/manual/en/customize-erpnext/custom-field' },
]

View File

@@ -180,7 +180,8 @@ def make_custom_fields():
'Sales Invoice Item': [hsn_sac_field],
'Purchase Order Item': [hsn_sac_field],
'Purchase Receipt Item': [hsn_sac_field],
'Purchase Invoice Item': [hsn_sac_field]
'Purchase Invoice Item': [hsn_sac_field],
'Material Request Item': [hsn_sac_field]
}
create_custom_fields(custom_fields)

View File

@@ -5,25 +5,52 @@ from erpnext.regional.india import states, state_numbers
from erpnext.controllers.taxes_and_totals import get_itemised_tax, get_itemised_taxable_amount
def validate_gstin_for_india(doc, method):
if not hasattr(doc, 'gstin'):
if not hasattr(doc, 'gstin') or not doc.gstin:
return
if doc.gstin:
doc.gstin = doc.gstin.upper()
if doc.gstin not in ["NA", "na"]:
p = re.compile("[0-9]{2}[a-zA-Z]{5}[0-9]{4}[a-zA-Z]{1}[1-9A-Za-z]{1}[Z]{1}[0-9a-zA-Z]{1}")
if not p.match(doc.gstin):
frappe.throw(_("Invalid GSTIN or Enter NA for Unregistered"))
doc.gstin = doc.gstin.upper().strip()
if not doc.gstin or doc.gstin == 'NA':
return
if len(doc.gstin) != 15:
frappe.throw(_("Invalid GSTIN! A GSTIN must have 15 characters."))
p = re.compile("^[0-9]{2}[A-Z]{4}[0-9A-Z]{1}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}[1-9A-Z]{1}[0-9A-Z]{1}$")
if not p.match(doc.gstin):
frappe.throw(_("Invalid GSTIN! The input you've entered doesn't match the format of GSTIN."))
validate_gstin_check_digit(doc.gstin)
if not doc.gst_state:
if doc.state in states:
doc.gst_state = doc.state
if not doc.state:
return
state = doc.state.lower()
states_lowercase = {s.lower():s for s in states}
if state in states_lowercase:
doc.gst_state = states_lowercase[state]
else:
return
if doc.gst_state:
doc.gst_state_number = state_numbers[doc.gst_state]
if doc.gstin and doc.gstin != "NA" and doc.gst_state_number != doc.gstin[:2]:
frappe.throw(_("First 2 digits of GSTIN should match with State number {0}")
.format(doc.gst_state_number))
doc.gst_state_number = state_numbers[doc.gst_state]
if doc.gst_state_number != doc.gstin[:2]:
frappe.throw(_("Invalid GSTIN! First 2 digits of GSTIN should match with State number {0}.")
.format(doc.gst_state_number))
def validate_gstin_check_digit(gstin):
''' Function to validate the check digit of the GSTIN.'''
factor = 1
total = 0
code_point_chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
mod = len(code_point_chars)
input_chars = gstin[:-1]
for char in input_chars:
digit = factor * code_point_chars.find(char)
digit = (digit // mod) + (digit % mod)
total += digit
factor = 2 if factor == 1 else 1
if gstin[-1] != code_point_chars[((mod - (total % mod)) % mod)]:
frappe.throw(_("Invalid GSTIN! The check digit validation has failed. " +
"Please ensure you've typed the GSTIN correctly."))
def get_itemised_tax_breakup_header(item_doctype, tax_accounts):
if frappe.get_meta(item_doctype).has_field('gst_hsn_code'):

View File

@@ -1,6 +1,11 @@
Selling management module. Includes forms for capturing / managing the sales process.
Selling management module. Includes forms for capturing / managing the sales process:
- Customer
- Campaign
- Quotation
- Sales Order
Moved to CRM Module:
- Lead
- Opportunity
- Quotation
- Sales Order

View File

@@ -173,6 +173,11 @@ class Customer(TransactionBase):
frappe.throw(_("""New credit limit is less than current outstanding amount for the customer. Credit limit has to be atleast {0}""").format(outstanding_amt))
def on_trash(self):
if self.customer_primary_contact:
frappe.db.sql("""update `tabCustomer`
set customer_primary_contact=null, mobile_no=null, email_id=null
where name=%s""", self.name)
delete_contact_and_address('Customer', self.name)
if self.lead_name:
frappe.db.sql("update `tabLead` set status='Interested' where name=%s", self.lead_name)

View File

@@ -96,6 +96,15 @@ class TestCustomer(unittest.TestCase):
so.save()
def test_delete_customer_contact(self):
customer = frappe.get_doc(
get_customer_dict('_Test Customer for delete')).insert(ignore_permissions=True)
customer.mobile_no = "8989889890"
customer.save()
self.assertTrue(customer.customer_primary_contact)
frappe.delete_doc('Customer', customer.name)
def test_disabled_customer(self):
make_test_records("Item")

View File

@@ -31,6 +31,26 @@ class TestQuotation(unittest.TestCase):
self.assertFalse(sales_order.get('payment_schedule'))
def test_make_sales_order_with_different_currency(self):
from erpnext.selling.doctype.quotation.quotation import make_sales_order
quotation = frappe.copy_doc(test_records[0])
quotation.transaction_date = nowdate()
quotation.valid_till = add_months(quotation.transaction_date, 1)
quotation.insert()
quotation.submit()
sales_order = make_sales_order(quotation.name)
sales_order.currency = "USD"
sales_order.conversion_rate = 20.0
sales_order.delivery_date = "2019-01-01"
sales_order.naming_series = "_T-Quotation-"
sales_order.transaction_date = nowdate()
sales_order.insert()
self.assertEquals(sales_order.currency, "USD")
self.assertNotEqual(sales_order.currency, quotation.currency)
def test_make_sales_order(self):
from erpnext.selling.doctype.quotation.quotation import make_sales_order

View File

@@ -15,6 +15,7 @@
"fields": [
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -44,11 +45,13 @@
"reqd": 1,
"search_index": 1,
"set_only_once": 0,
"translatable": 0,
"unique": 0,
"width": "150px"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -74,10 +77,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -102,10 +107,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -134,11 +141,13 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0,
"width": "150px"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -165,10 +174,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -197,11 +208,13 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0,
"width": "300px"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -227,10 +240,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -257,10 +272,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -288,10 +305,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -317,10 +336,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -349,11 +370,13 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0,
"width": "100px"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -383,11 +406,13 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0,
"width": "100px"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -412,10 +437,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -443,10 +470,12 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -473,10 +502,12 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -503,10 +534,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -532,10 +565,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -565,11 +600,13 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0,
"width": "100px"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -599,11 +636,13 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0,
"width": "100px"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -630,10 +669,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -662,10 +703,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -693,10 +736,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -725,10 +770,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -754,10 +801,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -787,11 +836,13 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0,
"width": "100px"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -820,10 +871,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -852,10 +905,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -880,10 +935,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -915,11 +972,13 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0,
"width": "100px"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -936,6 +995,7 @@
"label": "Net Rate",
"length": 0,
"no_copy": 0,
"options": "currency",
"permlevel": 0,
"precision": "",
"print_hide": 1,
@@ -946,10 +1006,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -979,11 +1041,13 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0,
"width": "100px"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1011,10 +1075,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1039,10 +1105,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1072,11 +1140,13 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0,
"width": "100px"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1103,10 +1173,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1136,11 +1208,13 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0,
"width": "100px"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1168,10 +1242,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1198,10 +1274,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -1228,10 +1306,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1258,10 +1338,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1288,10 +1370,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1317,10 +1401,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1348,10 +1434,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -1379,10 +1467,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1410,10 +1500,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1439,10 +1531,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1469,10 +1563,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1500,10 +1596,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1530,10 +1628,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1559,10 +1659,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1592,11 +1694,13 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0,
"width": "150px"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1626,11 +1730,13 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0,
"width": "150px"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1658,10 +1764,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1686,10 +1794,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
@@ -1717,10 +1827,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1750,10 +1862,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1783,6 +1897,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0,
"width": "150px"
}
@@ -1798,7 +1913,7 @@
"istable": 1,
"max_attachments": 0,
"menu_index": 0,
"modified": "2018-08-06 05:18:38.135668",
"modified": "2018-12-12 05:52:46.135944",
"modified_by": "Administrator",
"module": "Selling",
"name": "Quotation Item",
@@ -1811,5 +1926,6 @@
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0
"track_seen": 0,
"track_views": 0
}

View File

@@ -141,7 +141,7 @@ class SalesOrder(SellingController):
super(SalesOrder, self).validate_with_previous_doc({
"Quotation": {
"ref_dn_field": "prevdoc_docname",
"compare_fields": [["company", "="], ["currency", "="]]
"compare_fields": [["company", "="]]
}
})
@@ -552,7 +552,7 @@ def make_sales_invoice(source_name, target_doc=None, ignore_permissions=False):
def update_item(source, target, source_parent):
target.amount = flt(source.amount) - flt(source.billed_amt)
target.base_amount = target.amount * flt(source_parent.conversion_rate)
target.qty = target.amount / flt(source.rate) if (source.rate and source.billed_amt) else source.qty
target.qty = target.amount / flt(source.rate) if (source.rate and source.billed_amt) else source.qty - source.returned_qty
item = frappe.db.get_value("Item", target.item_code, ["item_group", "selling_cost_center"], as_dict=1)
target.cost_center = frappe.db.get_value("Project", source_parent.project, "cost_center") \

View File

@@ -22,7 +22,7 @@
<ul class="list-unstyled">
<li><a class="text-muted" href="#">{%= __("Go to the Desktop and start using ERPNext") %}</a></li>
<li><a class="text-muted" href="#modules/Learn">{%= __("View a list of all the help videos") %}</a></li>
<li><a class="text-muted" href="https://erpnext.org/docs/user" target="_blank">{%= __("Read the ERPNext Manual") %}</a></li>
<li><a class="text-muted" href="https://erpnext.com/docs/user" target="_blank">{%= __("Read the ERPNext Manual") %}</a></li>
<li><a class="text-muted" href="https://discuss.erpnext.com" target="_blank">{%= __("Community Forum") %}</a></li>
</ul>

View File

@@ -66,7 +66,7 @@ def place_order():
sales_order = frappe.get_doc(_make_sales_order(quotation.name, ignore_permissions=True))
for item in sales_order.get("items"):
item.reserved_warehouse, is_stock_item = frappe.db.get_value("Item",
item.item_code, ["website_warehouse", "is_stock_item"]) or None, None
item.item_code, ["website_warehouse", "is_stock_item"])
if is_stock_item:
item_stock = get_qty_in_stock(item.item_code, "website_warehouse")

View File

@@ -5,6 +5,7 @@ $.extend(cur_frm.cscript, {
onload: function() {
if(cur_frm.doc.__onload && cur_frm.doc.__onload.quotation_series) {
cur_frm.fields_dict.quotation_series.df.options = cur_frm.doc.__onload.quotation_series;
cur_frm.refresh_field("quotation_series");
}
},
refresh: function(){

View File

@@ -93,6 +93,29 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend(
refresh: function(doc, dt, dn) {
var me = this;
this._super();
if((!doc.is_return) && (doc.status!="Closed" || this.frm.is_new())) {
if (this.frm.doc.docstatus===0) {
this.frm.add_custom_button(__('Sales Order'),
function() {
erpnext.utils.map_current_doc({
method: "erpnext.selling.doctype.sales_order.sales_order.make_delivery_note",
source_doctype: "Sales Order",
target: me.frm,
setters: {
customer: me.frm.doc.customer || undefined,
},
get_query_filters: {
docstatus: 1,
status: ["!=", "Closed"],
per_delivered: ["<", 99.99],
company: me.frm.doc.company,
project: me.frm.doc.project || undefined,
}
})
}, __("Get items from"));
}
}
if (!doc.is_return && doc.status!="Closed") {
if(flt(doc.per_installed, 2) < 100 && doc.docstatus==1)
this.frm.add_custom_button(__('Installation Note'), function() {
@@ -114,27 +137,6 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend(
if (!doc.__islocal && doc.docstatus==1) {
this.frm.page.set_inner_btn_group_as_primary(__("Make"));
}
if (this.frm.doc.docstatus===0) {
this.frm.add_custom_button(__('Sales Order'),
function() {
erpnext.utils.map_current_doc({
method: "erpnext.selling.doctype.sales_order.sales_order.make_delivery_note",
source_doctype: "Sales Order",
target: me.frm,
setters: {
customer: me.frm.doc.customer || undefined,
},
get_query_filters: {
docstatus: 1,
status: ["!=", "Closed"],
per_delivered: ["<", 99.99],
company: me.frm.doc.company,
project: me.frm.doc.project || undefined,
}
})
}, __("Get items from"));
}
}
if (doc.docstatus==1) {

View File

@@ -382,8 +382,24 @@ def get_invoiced_qty_map(delivery_note):
return invoiced_qty_map
def get_returned_qty_map(sales_orders):
"""returns a map: {so_detail: returned_qty}"""
returned_qty_map = {}
for name, returned_qty in frappe.get_all('Sales Order Item', fields = ["name", "returned_qty"],
filters = {'parent': ('in', sales_orders), 'docstatus': 1}, as_list=1):
if not returned_qty_map.get(name):
returned_qty_map[name] = 0
returned_qty_map[name] += returned_qty
return returned_qty_map
@frappe.whitelist()
def make_sales_invoice(source_name, target_doc=None):
doc = frappe.get_doc('Delivery Note', source_name)
sales_orders = [d.against_sales_order for d in doc.items]
returned_qty_map = get_returned_qty_map(sales_orders)
invoiced_qty_map = get_invoiced_qty_map(source_name)
def set_missing_values(source, target):
@@ -403,7 +419,9 @@ def make_sales_invoice(source_name, target_doc=None):
target.update(get_fetch_values("Sales Invoice", 'company_address', target.company_address))
def update_item(source_doc, target_doc, source_parent):
target_doc.qty = source_doc.qty - invoiced_qty_map.get(source_doc.name, 0)
target_doc.qty = (source_doc.qty -
invoiced_qty_map.get(source_doc.name, 0) - returned_qty_map.get(source_doc.so_detail, 0))
if source_doc.serial_no and source_parent.per_billed > 0:
target_doc.serial_no = get_delivery_note_serial_no(source_doc.item_code,
target_doc.qty, source_parent.name)

View File

@@ -564,6 +564,24 @@ class TestDeliveryNote(unittest.TestCase):
self.assertEqual(dn.per_billed, 100)
self.assertEqual(dn.status, "Completed")
def test_make_sales_invoice_from_dn_for_returned_qty(self):
from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note
from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice
so = make_sales_order(qty=2)
so.submit()
dn = make_delivery_note(so.name)
dn.submit()
dn1 = create_delivery_note(is_return=1, return_against=dn.name, qty=-1, do_not_submit=True)
dn1.items[0].against_sales_order = so.name
dn1.items[0].so_detail = so.items[0].name
dn1.submit()
si = make_sales_invoice(dn.name)
self.assertEquals(si.items[0].qty, 1)
def create_delivery_note(**args):
dn = frappe.new_doc("Delivery Note")
args = frappe._dict(args)

View File

@@ -381,6 +381,9 @@ def make_purchase_invoice(source_name, target_doc=None):
doclist = get_mapped_doc("Purchase Receipt", source_name, {
"Purchase Receipt": {
"doctype": "Purchase Invoice",
"field_map": {
"supplier_warehouse": "supplier_warehouse"
},
"validation": {
"docstatus": ["=", 1],
},

View File

@@ -325,7 +325,8 @@ def make_purchase_receipt(**args):
"conversion_factor": args.conversion_factor or 1.0,
"serial_no": args.serial_no,
"stock_uom": args.stock_uom or "_Test UOM",
"uom": args.uom or "_Test UOM"
"uom": args.uom or "_Test UOM",
"cost_center": "_Test Cost Center - _TC"
})
if not args.do_not_save:

View File

@@ -270,24 +270,27 @@ class StockReconciliation(StockController):
@frappe.whitelist()
def get_items(warehouse, posting_date, posting_time):
items = frappe.get_list("Bin", fields=["item_code"], filters={"warehouse": warehouse}, as_list=1)
lft, rgt = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt"])
items = frappe.db.sql("""select item_code, warehouse from tabBin
where exists(select name from `tabWarehouse` where lft >= %s and rgt <= %s and name=`tabBin`.warehouse)
""", (lft, rgt))
items += frappe.get_list("Item", fields=["name"], filters= {"is_stock_item": 1, "has_serial_no": 0,
"has_batch_no": 0, "has_variants": 0, "disabled": 0, "default_warehouse": warehouse},
as_list=1)
items += frappe.db.sql("""select name, default_warehouse from tabItem
where exists(select name from `tabWarehouse` where lft >= %s and rgt <= %s and name=`tabItem`.default_warehouse)
and is_stock_item = 1 and has_serial_no = 0 and has_batch_no = 0 and has_variants = 0 and disabled = 0
""", (lft, rgt))
res = []
for item in set(items):
stock_bal = get_stock_balance(item[0], warehouse, posting_date, posting_time,
for item, wh in set(items):
stock_bal = get_stock_balance(item, wh, posting_date, posting_time,
with_valuation_rate=True)
if frappe.db.get_value("Item",item[0],"disabled") == 0:
if frappe.db.get_value("Item", item, "disabled") == 0:
res.append({
"item_code": item[0],
"warehouse": warehouse,
"item_code": item,
"warehouse": wh,
"qty": stock_bal[0],
"item_name": frappe.db.get_value('Item', item[0], 'item_name'),
"item_name": frappe.db.get_value('Item', item, 'item_name'),
"valuation_rate": stock_bal[1],
"current_qty": stock_bal[0],
"current_valuation_rate": stock_bal[1]

View File

@@ -10,7 +10,9 @@ from frappe.utils import flt, nowdate, nowtime
from erpnext.accounts.utils import get_stock_and_account_difference
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
from erpnext.stock.stock_ledger import get_previous_sle, update_entries_after
from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import EmptyStockReconciliationItemsError
from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import EmptyStockReconciliationItemsError, get_items
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
from erpnext.stock.doctype.item.test_item import make_item
class TestStockReconciliation(unittest.TestCase):
def setUp(self):
@@ -79,6 +81,17 @@ class TestStockReconciliation(unittest.TestCase):
set_perpetual_inventory(0)
def test_get_items(self):
create_warehouse("_Test Warehouse Group 1", {"is_group": 1})
create_warehouse("_Test Warehouse Ledger 1", {"is_group": 0, "parent_warehouse": "_Test Warehouse Group 1 - _TC"})
make_item("_Test Stock Reco Item", {"default_warehouse": "_Test Warehouse Ledger 1 - _TC",
"is_stock_item": 1, "opening_stock": 100, "valuation_rate": 100})
items = get_items("_Test Warehouse Group 1 - _TC", nowdate(), nowtime())
self.assertEqual(["_Test Stock Reco Item", "_Test Warehouse Ledger 1 - _TC", 100],
[items[0]["item_code"], items[0]["warehouse"], items[0]["qty"]])
def insert_existing_sle(self):
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry

View File

@@ -90,7 +90,7 @@ class TestWarehouse(unittest.TestCase):
self.assertTrue(frappe.db.get_value("Warehouse",
filters={"account": "Test Warehouse for Merging 2 - _TC"}))
def create_warehouse(warehouse_name):
def create_warehouse(warehouse_name, properties=None):
if not frappe.db.exists("Warehouse", warehouse_name + " - _TC"):
w = frappe.new_doc("Warehouse")
w.warehouse_name = warehouse_name
@@ -98,11 +98,13 @@ def create_warehouse(warehouse_name):
w.company = "_Test Company"
make_account_for_warehouse(warehouse_name, w)
w.account = warehouse_name + " - _TC"
if properties:
w.update(properties)
w.save()
def make_account_for_warehouse(warehouse_name, warehouse_obj):
if not frappe.db.exists("Account", warehouse_name + " - _TC"):
parent_account = frappe.db.get_value('Account',
parent_account = frappe.db.get_value('Account',
{'company': warehouse_obj.company, 'is_group':1, 'account_type': 'Stock'},'name')
account = create_account(account_name=warehouse_name, \
account_type="Stock", parent_account= parent_account, company=warehouse_obj.company)

View File

@@ -110,7 +110,7 @@ def get_reserved_qty(item_code, warehouse):
return flt(reserved_qty[0][0]) if reserved_qty else 0
def get_indented_qty(item_code, warehouse):
indented_qty = frappe.db.sql("""select sum(mr_item.qty - mr_item.ordered_qty)
indented_qty = frappe.db.sql("""select sum((mr_item.qty - mr_item.ordered_qty) * mr_item.conversion_factor)
from `tabMaterial Request Item` mr_item, `tabMaterial Request` mr
where mr_item.item_code=%s and mr_item.warehouse=%s
and mr_item.qty > mr_item.ordered_qty and mr_item.parent=mr.name

View File

@@ -16,7 +16,7 @@ def send_message(subject="Website Query", message="", sender="", status="Open"):
customer = frappe.db.sql("""select distinct dl.link_name from `tabDynamic Link` dl
left join `tabContact` c on dl.parent=c.name where dl.link_doctype='Customer'
and c.email_id='{email_id}'""".format(email_id=sender))
and c.email_id = %s""", sender)
if not customer:
lead = frappe.db.get_value('Lead', dict(email_id=sender))

View File

@@ -4,50 +4,35 @@
import frappe, erpnext
from frappe import _
from six import iteritems
def get_level():
activation_level = 0
sales_data = []
doctypes = {"Item": 5, "Customer": 5, "Sales Order": 2, "Sales Invoice": 2, "Purchase Order": 2, "Employee": 3, "Lead": 3, "Quotation": 3,
"Payment Entry": 2, "User": 5, "Student": 5, "Instructor": 5, "BOM": 3, "Journal Entry": 3, "Stock Entry": 3}
for doctype, min_count in iteritems(doctypes):
count = frappe.db.count(doctype)
if count > min_count:
activation_level += 1
sales_data.append({doctype: count})
if frappe.db.get_single_value('System Settings', 'setup_complete'):
activation_level = 1
if frappe.db.count('Item') > 5:
activation_level += 1
if frappe.db.count('Customer') > 5:
activation_level += 1
if frappe.db.count('Sales Order') > 2:
activation_level += 1
if frappe.db.count('Purchase Order') > 2:
activation_level += 1
if frappe.db.count('Employee') > 3:
activation_level += 1
if frappe.db.count('Lead') > 3:
activation_level += 1
if frappe.db.count('Payment Entry') > 2:
activation_level += 1
if frappe.db.count('Communication', dict(communication_medium='Email')) > 10:
activation_level += 1
if frappe.db.count('User') > 5:
activation_level += 1
if frappe.db.count('Student') > 5:
activation_level += 1
if frappe.db.count('Instructor') > 5:
communication_number = frappe.db.count('Communication', dict(communication_medium='Email'))
if communication_number > 10:
activation_level += 1
sales_data.append({"Communication": communication_number})
# recent login
if frappe.db.sql('select name from tabUser where last_login > date_sub(now(), interval 2 day) limit 1'):
activation_level += 1
return activation_level
level = {"activation_level": activation_level, "sales_data": sales_data}
return level
def get_help_messages():
'''Returns help messages to be shown on Desktop'''

View File

@@ -33,7 +33,7 @@ def get_slide_settings():
help_links=[
{
"label": _("Chart of Accounts"),
"url": ["https://erpnext.org/docs/user/manual/en/accounts/chart-of-accounts"]
"url": ["https://erpnext.com/docs/user/manual/en/accounts/chart-of-accounts"]
},
{
"label": _("Opening Balances"),
@@ -56,7 +56,7 @@ def get_slide_settings():
help_links=[
{
"label": _('Learn More'),
"url": ["https://erpnext.org/docs/user/manual/en/setting-up/setting-company-sales-goal"]
"url": ["https://erpnext.com/docs/user/manual/en/setting-up/setting-company-sales-goal"]
}
]
),
@@ -80,7 +80,7 @@ def get_slide_settings():
help_links=[
{
"label": _('Learn More'),
"url": ["https://erpnext.org/docs/user/manual/en/CRM/customer.html"]
"url": ["https://erpnext.com/docs/user/manual/en/CRM/customer.html"]
}
]
),
@@ -123,7 +123,7 @@ def get_slide_settings():
help_links=[
{
"label": _('Learn More'),
"url": ["https://erpnext.org/docs/user/manual/en/buying/supplier"]
"url": ["https://erpnext.com/docs/user/manual/en/buying/supplier"]
},
{
"label": _('Customers and Suppliers'),
@@ -261,7 +261,7 @@ def get_slide_settings():
help_links=[
{
"label": _('Learn More'),
"url": ["https://erpnext.org/docs/user/manual/en/setting-up/users-and-permissions"]
"url": ["https://erpnext.com/docs/user/manual/en/setting-up/users-and-permissions"]
},
{
"label": _('Users and Permissions'),

View File

@@ -1,4 +1,4 @@
frappe
unidecode
pygithub
googlemaps
Unidecode==1.1.1
PyGithub==1.43.8
googlemaps==3.0.2