Merge pull request #21252 from nextchamp-saqib/tax-breakup-for-cn
fix: show positive taxes in credit notes
diff --git a/CODEOWNERS b/CODEOWNERS
new file mode 100644
index 0000000..5e1113d
--- /dev/null
+++ b/CODEOWNERS
@@ -0,0 +1,19 @@
+# Each line is a file pattern followed by one or more owners.
+
+# These owners will be the default owners for everything in
+# the repo. Unless a later match takes precedence,
+
+* @nabinhait
+manufacturing/ @rohitwaghchaure
+accounts/ @deepeshgarg007 @nextchamp-saqib
+loan_management/ @deepeshgarg007
+pos* @nextchamp-saqib
+assets/ @nextchamp-saqib
+stock/ @marination @rohitwaghchaure
+buying/ @marination @rohitwaghchaure
+hr/ @Anurag810
+projects/ @hrwX
+support/ @hrwX
+healthcare/ @ruchamahabal
+erpnext_integrations/ @Mangesh-Khairnar
+requirements.txt @gavindsouza
diff --git a/erpnext/accounts/desk_page/accounting/accounting.json b/erpnext/accounts/desk_page/accounting/accounting.json
index 7a777f9..8566ead 100644
--- a/erpnext/accounts/desk_page/accounting/accounting.json
+++ b/erpnext/accounts/desk_page/accounting/accounting.json
@@ -1,83 +1,96 @@
{
"cards": [
{
- "links": "[\n {\n \"description\": \"Company (not Customer or Supplier) master.\",\n \"label\": \"Company\",\n \"name\": \"Company\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tree of financial accounts.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Chart of Accounts\",\n \"name\": \"Account\",\n \"onboard\": 1,\n \"route\": \"#Tree/Account\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Accounts Settings\",\n \"name\": \"Accounts Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Financial / accounting year.\",\n \"label\": \"Fiscal Year\",\n \"name\": \"Fiscal Year\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Accounting Dimension\",\n \"name\": \"Accounting Dimension\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Finance Book\",\n \"name\": \"Finance Book\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Accounting Period\",\n \"name\": \"Accounting Period\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Payment Terms based on conditions\",\n \"label\": \"Payment Term\",\n \"name\": \"Payment Term\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Accounting Masters"
+ "hidden": 0,
+ "label": "Accounting Masters",
+ "links": "[\n {\n \"description\": \"Company (not Customer or Supplier) master.\",\n \"label\": \"Company\",\n \"name\": \"Company\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tree of financial accounts.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Chart of Accounts\",\n \"name\": \"Account\",\n \"onboard\": 1,\n \"route\": \"#Tree/Account\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Accounts Settings\",\n \"name\": \"Accounts Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Financial / accounting year.\",\n \"label\": \"Fiscal Year\",\n \"name\": \"Fiscal Year\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Accounting Dimension\",\n \"name\": \"Accounting Dimension\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Finance Book\",\n \"name\": \"Finance Book\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Accounting Period\",\n \"name\": \"Accounting Period\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Payment Terms based on conditions\",\n \"label\": \"Payment Term\",\n \"name\": \"Payment Term\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Accounting journal entries.\",\n \"label\": \"Journal Entry\",\n \"name\": \"Journal Entry\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"General Ledger\",\n \"name\": \"General Ledger\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Customer Ledger Summary\",\n \"name\": \"Customer Ledger Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Supplier Ledger Summary\",\n \"name\": \"Supplier Ledger Summary\",\n \"type\": \"report\"\n }\n]",
- "title": "General Ledger"
+ "hidden": 0,
+ "label": "General Ledger",
+ "links": "[\n {\n \"description\": \"Accounting journal entries.\",\n \"label\": \"Journal Entry\",\n \"name\": \"Journal Entry\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"General Ledger\",\n \"name\": \"General Ledger\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Customer Ledger Summary\",\n \"name\": \"Customer Ledger Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Supplier Ledger Summary\",\n \"name\": \"Supplier Ledger Summary\",\n \"type\": \"report\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Bills raised to Customers.\",\n \"label\": \"Sales Invoice\",\n \"name\": \"Sales Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customer database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bank/Cash transactions against party or for internal transfer\",\n \"label\": \"Payment Entry\",\n \"name\": \"Payment Entry\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Payment Request\",\n \"label\": \"Payment Request\",\n \"name\": \"Payment Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable\",\n \"name\": \"Accounts Receivable\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable Summary\",\n \"name\": \"Accounts Receivable Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Register\",\n \"name\": \"Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Sales Register\",\n \"name\": \"Item-wise Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Ordered Items To Be Billed\",\n \"name\": \"Ordered Items To Be Billed\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Delivered Items To Be Billed\",\n \"name\": \"Delivered Items To Be Billed\",\n \"type\": \"report\"\n }\n]",
- "title": "Accounts Receivable"
+ "hidden": 0,
+ "label": "Accounts Receivable",
+ "links": "[\n {\n \"description\": \"Bills raised to Customers.\",\n \"label\": \"Sales Invoice\",\n \"name\": \"Sales Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customer database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bank/Cash transactions against party or for internal transfer\",\n \"label\": \"Payment Entry\",\n \"name\": \"Payment Entry\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Payment Request\",\n \"label\": \"Payment Request\",\n \"name\": \"Payment Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable\",\n \"name\": \"Accounts Receivable\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable Summary\",\n \"name\": \"Accounts Receivable Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Register\",\n \"name\": \"Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Sales Register\",\n \"name\": \"Item-wise Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Ordered Items To Be Billed\",\n \"name\": \"Ordered Items To Be Billed\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Delivered Items To Be Billed\",\n \"name\": \"Delivered Items To Be Billed\",\n \"type\": \"report\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Bills raised by Suppliers.\",\n \"label\": \"Purchase Invoice\",\n \"name\": \"Purchase Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Supplier database.\",\n \"label\": \"Supplier\",\n \"name\": \"Supplier\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bank/Cash transactions against party or for internal transfer\",\n \"label\": \"Payment Entry\",\n \"name\": \"Payment Entry\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Payable\",\n \"name\": \"Accounts Payable\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Payable Summary\",\n \"name\": \"Accounts Payable Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Purchase Register\",\n \"name\": \"Purchase Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Purchase Register\",\n \"name\": \"Item-wise Purchase Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Purchase Order Items To Be Billed\",\n \"name\": \"Purchase Order Items To Be Billed\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Received Items To Be Billed\",\n \"name\": \"Received Items To Be Billed\",\n \"type\": \"report\"\n }\n]",
- "title": "Accounts Payable"
+ "hidden": 0,
+ "label": "Accounts Payable",
+ "links": "[\n {\n \"description\": \"Bills raised by Suppliers.\",\n \"label\": \"Purchase Invoice\",\n \"name\": \"Purchase Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Supplier database.\",\n \"label\": \"Supplier\",\n \"name\": \"Supplier\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bank/Cash transactions against party or for internal transfer\",\n \"label\": \"Payment Entry\",\n \"name\": \"Payment Entry\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Payable\",\n \"name\": \"Accounts Payable\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Payable Summary\",\n \"name\": \"Accounts Payable Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Purchase Register\",\n \"name\": \"Purchase Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Purchase Register\",\n \"name\": \"Item-wise Purchase Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Purchase Order Items To Be Billed\",\n \"name\": \"Purchase Order Items To Be Billed\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Received Items To Be Billed\",\n \"name\": \"Received Items To Be Billed\",\n \"type\": \"report\"\n }\n]"
},
{
- "icon": "fa fa-table",
- "links": "[\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Trial Balance for Party\",\n \"name\": \"Trial Balance for Party\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Journal Entry\"\n ],\n \"doctype\": \"Journal Entry\",\n \"is_query_report\": true,\n \"label\": \"Payment Period Based On Invoice Date\",\n \"name\": \"Payment Period Based On Invoice Date\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Partners Commission\",\n \"name\": \"Sales Partners Commission\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customer Credit Balance\",\n \"name\": \"Customer Credit Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Payment Summary\",\n \"name\": \"Sales Payment Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Address\"\n ],\n \"doctype\": \"Address\",\n \"is_query_report\": true,\n \"label\": \"Address And Contacts\",\n \"name\": \"Address And Contacts\",\n \"type\": \"report\"\n }\n]",
- "title": "Reports"
+ "hidden": 0,
+ "label": "Reports",
+ "links": "[\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Trial Balance for Party\",\n \"name\": \"Trial Balance for Party\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Journal Entry\"\n ],\n \"doctype\": \"Journal Entry\",\n \"is_query_report\": true,\n \"label\": \"Payment Period Based On Invoice Date\",\n \"name\": \"Payment Period Based On Invoice Date\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Partners Commission\",\n \"name\": \"Sales Partners Commission\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customer Credit Balance\",\n \"name\": \"Customer Credit Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Payment Summary\",\n \"name\": \"Sales Payment Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Address\"\n ],\n \"doctype\": \"Address\",\n \"is_query_report\": true,\n \"label\": \"Address And Contacts\",\n \"name\": \"Address And Contacts\",\n \"type\": \"report\"\n }\n]"
},
{
- "links": "[\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Trial Balance\",\n \"name\": \"Trial Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Profit and Loss Statement\",\n \"name\": \"Profit and Loss Statement\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Balance Sheet\",\n \"name\": \"Balance Sheet\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Cash Flow\",\n \"name\": \"Cash Flow\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Consolidated Financial Statement\",\n \"name\": \"Consolidated Financial Statement\",\n \"type\": \"report\"\n }\n]",
- "title": "Financial Statements"
+ "hidden": 0,
+ "label": "Financial Statements",
+ "links": "[\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Trial Balance\",\n \"name\": \"Trial Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Profit and Loss Statement\",\n \"name\": \"Profit and Loss Statement\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Balance Sheet\",\n \"name\": \"Balance Sheet\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Cash Flow\",\n \"name\": \"Cash Flow\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Consolidated Financial Statement\",\n \"name\": \"Consolidated Financial Statement\",\n \"type\": \"report\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Enable / disable currencies.\",\n \"label\": \"Currency\",\n \"name\": \"Currency\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Currency exchange rate master.\",\n \"label\": \"Currency Exchange\",\n \"name\": \"Currency Exchange\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Exchange Rate Revaluation master.\",\n \"label\": \"Exchange Rate Revaluation\",\n \"name\": \"Exchange Rate Revaluation\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Multi Currency"
+ "hidden": 0,
+ "label": "Multi Currency",
+ "links": "[\n {\n \"description\": \"Enable / disable currencies.\",\n \"label\": \"Currency\",\n \"name\": \"Currency\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Currency exchange rate master.\",\n \"label\": \"Currency Exchange\",\n \"name\": \"Currency Exchange\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Exchange Rate Revaluation master.\",\n \"label\": \"Exchange Rate Revaluation\",\n \"name\": \"Exchange Rate Revaluation\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-cog",
- "links": "[\n {\n \"description\": \"Setup Gateway accounts.\",\n \"label\": \"Payment Gateway Account\",\n \"name\": \"Payment Gateway Account\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Template of terms or contract.\",\n \"label\": \"Terms and Conditions Template\",\n \"name\": \"Terms and Conditions\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"e.g. Bank, Cash, Credit Card\",\n \"label\": \"Mode of Payment\",\n \"name\": \"Mode of Payment\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Settings"
+ "hidden": 0,
+ "label": "Settings",
+ "links": "[\n {\n \"description\": \"Setup Gateway accounts.\",\n \"label\": \"Payment Gateway Account\",\n \"name\": \"Payment Gateway Account\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Template of terms or contract.\",\n \"label\": \"Terms and Conditions Template\",\n \"name\": \"Terms and Conditions\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"e.g. Bank, Cash, Credit Card\",\n \"label\": \"Mode of Payment\",\n \"name\": \"Mode of Payment\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Bank\",\n \"name\": \"Bank\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Bank Account\",\n \"name\": \"Bank Account\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Bank Statement Transaction Entry\",\n \"name\": \"Bank Statement Transaction Entry\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Bank Statement Settings\",\n \"name\": \"Bank Statement Settings\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Bank Statement"
+ "hidden": 0,
+ "label": "Bank Statement",
+ "links": "[\n {\n \"label\": \"Bank\",\n \"name\": \"Bank\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Bank Account\",\n \"name\": \"Bank Account\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Bank Statement Transaction Entry\",\n \"name\": \"Bank Statement Transaction Entry\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Bank Statement Settings\",\n \"name\": \"Bank Statement Settings\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Match non-linked Invoices and Payments.\",\n \"label\": \"Match Payments with Invoices\",\n \"name\": \"Payment Reconciliation\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Update bank payment dates with journals.\",\n \"label\": \"Update Bank Transaction Dates\",\n \"name\": \"Bank Reconciliation\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Invoice Discounting\",\n \"name\": \"Invoice Discounting\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Journal Entry\"\n ],\n \"doctype\": \"Journal Entry\",\n \"is_query_report\": true,\n \"label\": \"Bank Reconciliation Statement\",\n \"name\": \"Bank Reconciliation Statement\",\n \"type\": \"report\"\n },\n {\n \"icon\": \"fa fa-bar-chart\",\n \"label\": \"Bank Reconciliation\",\n \"name\": \"bank-reconciliation\",\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Journal Entry\"\n ],\n \"doctype\": \"Journal Entry\",\n \"is_query_report\": true,\n \"label\": \"Bank Clearance Summary\",\n \"name\": \"Bank Clearance Summary\",\n \"type\": \"report\"\n },\n {\n \"label\": \"Bank Guarantee\",\n \"name\": \"Bank Guarantee\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Setup cheque dimensions for printing\",\n \"label\": \"Cheque Print Template\",\n \"name\": \"Cheque Print Template\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Banking and Payments"
+ "hidden": 0,
+ "label": "Banking and Payments",
+ "links": "[\n {\n \"description\": \"Match non-linked Invoices and Payments.\",\n \"label\": \"Match Payments with Invoices\",\n \"name\": \"Payment Reconciliation\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Update bank payment dates with journals.\",\n \"label\": \"Update Bank Transaction Dates\",\n \"name\": \"Bank Reconciliation\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Invoice Discounting\",\n \"name\": \"Invoice Discounting\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Journal Entry\"\n ],\n \"doctype\": \"Journal Entry\",\n \"is_query_report\": true,\n \"label\": \"Bank Reconciliation Statement\",\n \"name\": \"Bank Reconciliation Statement\",\n \"type\": \"report\"\n },\n {\n \"icon\": \"fa fa-bar-chart\",\n \"label\": \"Bank Reconciliation\",\n \"name\": \"bank-reconciliation\",\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Journal Entry\"\n ],\n \"doctype\": \"Journal Entry\",\n \"is_query_report\": true,\n \"label\": \"Bank Clearance Summary\",\n \"name\": \"Bank Clearance Summary\",\n \"type\": \"report\"\n },\n {\n \"label\": \"Bank Guarantee\",\n \"name\": \"Bank Guarantee\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Setup cheque dimensions for printing\",\n \"label\": \"Cheque Print Template\",\n \"name\": \"Cheque Print Template\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Subscription Plan\",\n \"name\": \"Subscription Plan\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Subscription\",\n \"name\": \"Subscription\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Subscription Settings\",\n \"name\": \"Subscription Settings\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Subscription Management"
+ "hidden": 0,
+ "label": "Subscription Management",
+ "links": "[\n {\n \"label\": \"Subscription Plan\",\n \"name\": \"Subscription Plan\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Subscription\",\n \"name\": \"Subscription\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Subscription Settings\",\n \"name\": \"Subscription Settings\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"GST Settings\",\n \"name\": \"GST Settings\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"GST HSN Code\",\n \"name\": \"GST HSN Code\",\n \"type\": \"doctype\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GSTR-1\",\n \"name\": \"GSTR-1\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GSTR-2\",\n \"name\": \"GSTR-2\",\n \"type\": \"report\"\n },\n {\n \"label\": \"GSTR 3B Report\",\n \"name\": \"GSTR 3B Report\",\n \"type\": \"doctype\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GST Sales Register\",\n \"name\": \"GST Sales Register\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GST Purchase Register\",\n \"name\": \"GST Purchase Register\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GST Itemised Sales Register\",\n \"name\": \"GST Itemised Sales Register\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GST Itemised Purchase Register\",\n \"name\": \"GST Itemised Purchase Register\",\n \"type\": \"report\"\n },\n {\n \"country\": \"India\",\n \"description\": \"C-Form records\",\n \"label\": \"C-Form\",\n \"name\": \"C-Form\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Goods and Services Tax (GST India)"
+ "hidden": 0,
+ "label": "Goods and Services Tax (GST India)",
+ "links": "[\n {\n \"label\": \"GST Settings\",\n \"name\": \"GST Settings\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"GST HSN Code\",\n \"name\": \"GST HSN Code\",\n \"type\": \"doctype\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GSTR-1\",\n \"name\": \"GSTR-1\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GSTR-2\",\n \"name\": \"GSTR-2\",\n \"type\": \"report\"\n },\n {\n \"label\": \"GSTR 3B Report\",\n \"name\": \"GSTR 3B Report\",\n \"type\": \"doctype\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GST Sales Register\",\n \"name\": \"GST Sales Register\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GST Purchase Register\",\n \"name\": \"GST Purchase Register\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GST Itemised Sales Register\",\n \"name\": \"GST Itemised Sales Register\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GST Itemised Purchase Register\",\n \"name\": \"GST Itemised Purchase Register\",\n \"type\": \"report\"\n },\n {\n \"country\": \"India\",\n \"description\": \"C-Form records\",\n \"label\": \"C-Form\",\n \"name\": \"C-Form\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-microchip ",
- "links": "[\n {\n \"description\": \"List of available Shareholders with folio numbers\",\n \"label\": \"Shareholder\",\n \"name\": \"Shareholder\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"List of all share transactions\",\n \"label\": \"Share Transfer\",\n \"name\": \"Share Transfer\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Share Transfer\"\n ],\n \"doctype\": \"Share Transfer\",\n \"is_query_report\": true,\n \"label\": \"Share Ledger\",\n \"name\": \"Share Ledger\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Share Transfer\"\n ],\n \"doctype\": \"Share Transfer\",\n \"is_query_report\": true,\n \"label\": \"Share Balance\",\n \"name\": \"Share Balance\",\n \"type\": \"report\"\n }\n]",
- "title": "Share Management"
+ "hidden": 0,
+ "label": "Share Management",
+ "links": "[\n {\n \"description\": \"List of available Shareholders with folio numbers\",\n \"label\": \"Shareholder\",\n \"name\": \"Shareholder\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"List of all share transactions\",\n \"label\": \"Share Transfer\",\n \"name\": \"Share Transfer\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Share Transfer\"\n ],\n \"doctype\": \"Share Transfer\",\n \"is_query_report\": true,\n \"label\": \"Share Ledger\",\n \"name\": \"Share Ledger\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Share Transfer\"\n ],\n \"doctype\": \"Share Transfer\",\n \"is_query_report\": true,\n \"label\": \"Share Balance\",\n \"name\": \"Share Balance\",\n \"type\": \"report\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Tree of financial Cost Centers.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Chart of Cost Centers\",\n \"name\": \"Cost Center\",\n \"route\": \"#Tree/Cost Center\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Define budget for a financial year.\",\n \"label\": \"Budget\",\n \"name\": \"Budget\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Accounting Dimension\",\n \"name\": \"Accounting Dimension\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Cost Center\"\n ],\n \"doctype\": \"Cost Center\",\n \"is_query_report\": true,\n \"label\": \"Budget Variance Report\",\n \"name\": \"Budget Variance Report\",\n \"type\": \"report\"\n },\n {\n \"description\": \"Seasonality for setting budgets, targets etc.\",\n \"label\": \"Monthly Distribution\",\n \"name\": \"Monthly Distribution\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Cost Center and Budgeting"
+ "hidden": 0,
+ "label": "Cost Center and Budgeting",
+ "links": "[\n {\n \"description\": \"Tree of financial Cost Centers.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Chart of Cost Centers\",\n \"name\": \"Cost Center\",\n \"route\": \"#Tree/Cost Center\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Define budget for a financial year.\",\n \"label\": \"Budget\",\n \"name\": \"Budget\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Accounting Dimension\",\n \"name\": \"Accounting Dimension\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Cost Center\"\n ],\n \"doctype\": \"Cost Center\",\n \"is_query_report\": true,\n \"label\": \"Budget Variance Report\",\n \"name\": \"Budget Variance Report\",\n \"type\": \"report\"\n },\n {\n \"description\": \"Seasonality for setting budgets, targets etc.\",\n \"label\": \"Monthly Distribution\",\n \"name\": \"Monthly Distribution\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Opening Invoice Creation Tool\",\n \"name\": \"Opening Invoice Creation Tool\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Chart of Accounts Importer\",\n \"name\": \"Chart of Accounts Importer\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Close Balance Sheet and book Profit or Loss.\",\n \"label\": \"Period Closing Voucher\",\n \"name\": \"Period Closing Voucher\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Opening and Closing"
+ "hidden": 0,
+ "label": "Opening and Closing",
+ "links": "[\n {\n \"label\": \"Opening Invoice Creation Tool\",\n \"name\": \"Opening Invoice Creation Tool\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Chart of Accounts Importer\",\n \"name\": \"Chart of Accounts Importer\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Close Balance Sheet and book Profit or Loss.\",\n \"label\": \"Period Closing Voucher\",\n \"name\": \"Period Closing Voucher\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Tax template for selling transactions.\",\n \"label\": \"Sales Taxes and Charges Template\",\n \"name\": \"Sales Taxes and Charges Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax template for buying transactions.\",\n \"label\": \"Purchase Taxes and Charges Template\",\n \"name\": \"Purchase Taxes and Charges Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax template for item tax rates.\",\n \"label\": \"Item Tax Template\",\n \"name\": \"Item Tax Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax Category for overriding tax rates.\",\n \"label\": \"Tax Category\",\n \"name\": \"Tax Category\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax Rule for transactions.\",\n \"label\": \"Tax Rule\",\n \"name\": \"Tax Rule\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax Withholding rates to be applied on transactions.\",\n \"label\": \"Tax Withholding Category\",\n \"name\": \"Tax Withholding Category\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Taxes"
+ "hidden": 0,
+ "label": "Taxes",
+ "links": "[\n {\n \"description\": \"Tax template for selling transactions.\",\n \"label\": \"Sales Taxes and Charges Template\",\n \"name\": \"Sales Taxes and Charges Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax template for buying transactions.\",\n \"label\": \"Purchase Taxes and Charges Template\",\n \"name\": \"Purchase Taxes and Charges Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax template for item tax rates.\",\n \"label\": \"Item Tax Template\",\n \"name\": \"Item Tax Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax Category for overriding tax rates.\",\n \"label\": \"Tax Category\",\n \"name\": \"Tax Category\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax Rule for transactions.\",\n \"label\": \"Tax Rule\",\n \"name\": \"Tax Rule\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax Withholding rates to be applied on transactions.\",\n \"label\": \"Tax Withholding Category\",\n \"name\": \"Tax Withholding Category\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Gross Profit\",\n \"name\": \"Gross Profit\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Profitability Analysis\",\n \"name\": \"Profitability Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Invoice Trends\",\n \"name\": \"Sales Invoice Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Purchase Invoice Trends\",\n \"name\": \"Purchase Invoice Trends\",\n \"type\": \"report\"\n }\n]",
- "title": "Profitability"
+ "hidden": 0,
+ "label": "Profitability",
+ "links": "[\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Gross Profit\",\n \"name\": \"Gross Profit\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Profitability Analysis\",\n \"name\": \"Profitability Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Invoice Trends\",\n \"name\": \"Sales Invoice Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Purchase Invoice Trends\",\n \"name\": \"Purchase Invoice Trends\",\n \"type\": \"report\"\n }\n]"
}
],
"category": "Modules",
"charts": [
{
"chart_name": "Bank Balance",
- "label": "Bank Balance",
- "size": "Full"
+ "label": "Bank Balance"
}
],
"creation": "2020-03-02 15:41:59.515192",
@@ -90,7 +103,7 @@
"idx": 0,
"is_standard": 1,
"label": "Accounting",
- "modified": "2020-03-12 16:30:35.580450",
+ "modified": "2020-04-01 11:28:50.925719",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounting",
@@ -99,37 +112,37 @@
"pin_to_top": 0,
"shortcuts": [
{
- "is_query_report": 0,
+ "label": "Account",
"link_to": "Account",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Journal Entry",
"link_to": "Journal Entry",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Payment Entry",
"link_to": "Payment Entry",
"type": "DocType"
},
{
- "is_query_report": 1,
+ "label": "Accounts Receivable",
"link_to": "Accounts Receivable",
"type": "Report"
},
{
- "is_query_report": 0,
+ "label": "General Ledger",
"link_to": "General Ledger",
"type": "Report"
},
{
- "is_query_report": 0,
+ "label": "Profit and Loss Statement",
"link_to": "Profit and Loss Statement",
"type": "Report"
},
{
- "is_query_report": 0,
+ "label": "Trial Balance",
"link_to": "Trial Balance",
"type": "Report"
}
diff --git a/erpnext/accounts/doctype/account/account_tree.js b/erpnext/accounts/doctype/account/account_tree.js
index efac1af..f62d076 100644
--- a/erpnext/accounts/doctype/account/account_tree.js
+++ b/erpnext/accounts/doctype/account/account_tree.js
@@ -1,7 +1,7 @@
frappe.provide("frappe.treeview_settings")
frappe.treeview_settings["Account"] = {
- breadcrumbs: "Accounts",
+ breadcrumb: "Accounts",
title: __("Chart Of Accounts"),
get_tree_root: false,
filters: [
diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
index 462d967..14fdffc 100644
--- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
+++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
@@ -193,7 +193,7 @@
all_dimensions = []
lft, rgt = frappe.db.get_value(doctype, dimension, ["lft", "rgt"])
- children = frappe.get_all(doctype, filters={"lft": [">=", lft], "rgt": ["<=", rgt]})
+ children = frappe.get_all(doctype, filters={"lft": [">=", lft], "rgt": ["<=", rgt]}, order_by="lft")
all_dimensions += [c.name for c in children]
return all_dimensions
diff --git a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
index b6f5396..fa4d40e 100644
--- a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
+++ b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
@@ -164,7 +164,7 @@
error_messages = []
for i in data:
- account_name, _, account_number, is_group, account_type, root_type = i
+ account_name, dummy, account_number, is_group, account_type, root_type = i
if not account_name:
error_messages.append("Row {0}: Please enter Account Name".format(line_no))
diff --git a/erpnext/accounts/doctype/cost_center/cost_center_tree.js b/erpnext/accounts/doctype/cost_center/cost_center_tree.js
index 16d9734..fde4123 100644
--- a/erpnext/accounts/doctype/cost_center/cost_center_tree.js
+++ b/erpnext/accounts/doctype/cost_center/cost_center_tree.js
@@ -1,5 +1,5 @@
frappe.treeview_settings["Cost Center"] = {
- breadcrumbs: "Accounts",
+ breadcrumb: "Accounts",
get_tree_root: false,
filters: [{
fieldname: "company",
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index d208087..b7c97a7 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -156,8 +156,11 @@
frm.toggle_display("base_paid_amount", frm.doc.paid_from_account_currency != company_currency);
- frm.toggle_display("base_received_amount", (frm.doc.paid_to_account_currency != company_currency &&
- frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency));
+ frm.toggle_display("base_received_amount", (
+ frm.doc.paid_to_account_currency != company_currency
+ && frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency
+ && frm.doc.base_paid_amount != frm.doc.base_received_amount
+ ));
frm.toggle_display("received_amount", (frm.doc.payment_type=="Internal Transfer" ||
frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency))
@@ -501,6 +504,7 @@
paid_amount: function(frm) {
frm.set_value("base_paid_amount", flt(frm.doc.paid_amount) * flt(frm.doc.source_exchange_rate));
frm.trigger("reset_received_amount");
+ frm.events.hide_unhide_fields(frm);
},
received_amount: function(frm) {
@@ -524,6 +528,7 @@
frm.events.set_unallocated_amount(frm);
frm.set_paid_amount_based_on_received_amount = false;
+ frm.events.hide_unhide_fields(frm);
},
reset_received_amount: function(frm) {
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 55d2758..a453e95 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -81,7 +81,12 @@
self.update_advance_paid()
self.update_expense_claim()
self.delink_advance_entry_references()
+ self.set_payment_req_status()
self.set_status()
+
+ def set_payment_req_status(self):
+ from erpnext.accounts.doctype.payment_request.payment_request import update_payment_req_status
+ update_payment_req_status(self, None)
def update_outstanding_amounts(self):
self.set_missing_ref_details(force=True)
diff --git a/erpnext/accounts/doctype/payment_order/payment_order.js b/erpnext/accounts/doctype/payment_order/payment_order.js
index d6d4946..d12e474 100644
--- a/erpnext/accounts/doctype/payment_order/payment_order.js
+++ b/erpnext/accounts/doctype/payment_order/payment_order.js
@@ -15,11 +15,11 @@
if (frm.doc.docstatus == 0) {
frm.add_custom_button(__('Payment Request'), function() {
frm.trigger("get_from_payment_request");
- }, __("Get from"));
+ }, __("Get Payments from"));
frm.add_custom_button(__('Payment Entry'), function() {
frm.trigger("get_from_payment_entry");
- }, __("Get from"));
+ }, __("Get Payments from"));
frm.trigger('remove_button');
}
diff --git a/erpnext/accounts/doctype/payment_order/payment_order.json b/erpnext/accounts/doctype/payment_order/payment_order.json
index 2e12ad3..2ed0a4a 100644
--- a/erpnext/accounts/doctype/payment_order/payment_order.json
+++ b/erpnext/accounts/doctype/payment_order/payment_order.json
@@ -59,7 +59,6 @@
"fieldtype": "Section Break"
},
{
- "allow_bulk_edit": 1,
"fieldname": "references",
"fieldtype": "Table",
"label": "Payment Order Reference",
@@ -108,7 +107,7 @@
}
],
"is_submittable": 1,
- "modified": "2019-05-14 17:12:24.912666",
+ "modified": "2020-04-06 18:00:56.022642",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Order",
diff --git a/erpnext/accounts/doctype/payment_request/payment_request.json b/erpnext/accounts/doctype/payment_request/payment_request.json
index c1559a7..97ae5ff 100644
--- a/erpnext/accounts/doctype/payment_request/payment_request.json
+++ b/erpnext/accounts/doctype/payment_request/payment_request.json
@@ -1,1560 +1,387 @@
{
- "allow_copy": 0,
- "allow_events_in_timeline": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "autoname": "naming_series:",
- "beta": 0,
- "creation": "2015-12-15 22:23:24.745065",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 0,
- "engine": "InnoDB",
+ "autoname": "naming_series:",
+ "creation": "2015-12-15 22:23:24.745065",
+ "doctype": "DocType",
+ "engine": "InnoDB",
+ "field_order": [
+ "payment_request_type",
+ "transaction_date",
+ "column_break_2",
+ "naming_series",
+ "mode_of_payment",
+ "party_details",
+ "party_type",
+ "party",
+ "column_break_4",
+ "reference_doctype",
+ "reference_name",
+ "transaction_details",
+ "grand_total",
+ "is_a_subscription",
+ "column_break_18",
+ "currency",
+ "subscription_section",
+ "subscription_plans",
+ "bank_account_details",
+ "bank_account",
+ "bank",
+ "bank_account_no",
+ "account",
+ "column_break_11",
+ "iban",
+ "branch_code",
+ "swift_number",
+ "recipient_and_message",
+ "print_format",
+ "email_to",
+ "subject",
+ "column_break_9",
+ "payment_gateway_account",
+ "status",
+ "make_sales_invoice",
+ "section_break_10",
+ "message",
+ "message_examples",
+ "mute_email",
+ "payment_url",
+ "section_break_7",
+ "payment_gateway",
+ "payment_account",
+ "payment_order",
+ "amended_from"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "Inward",
- "fieldname": "payment_request_type",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Payment Request Type",
- "length": 0,
- "no_copy": 0,
- "options": "Outward\nInward",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "Inward",
+ "fieldname": "payment_request_type",
+ "fieldtype": "Select",
+ "label": "Payment Request Type",
+ "options": "Outward\nInward",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "transaction_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Transaction Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "transaction_date",
+ "fieldtype": "Date",
+ "label": "Transaction Date"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_2",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_2",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "naming_series",
- "fieldtype": "Select",
- "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": "Series",
- "length": 0,
- "no_copy": 1,
- "options": "ACC-PRQ-.YYYY.-",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "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": 1,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "naming_series",
+ "fieldtype": "Select",
+ "in_list_view": 1,
+ "label": "Series",
+ "no_copy": 1,
+ "options": "ACC-PRQ-.YYYY.-",
+ "print_hide": 1,
+ "reqd": 1,
+ "set_only_once": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "mode_of_payment",
- "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": "Mode of Payment",
- "length": 0,
- "no_copy": 0,
- "options": "Mode of Payment",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "mode_of_payment",
+ "fieldtype": "Link",
+ "label": "Mode of Payment",
+ "options": "Mode of Payment"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "party_details",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Party Details",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "party_details",
+ "fieldtype": "Section Break",
+ "label": "Party Details"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "party_type",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Party Type",
- "length": 0,
- "no_copy": 0,
- "options": "DocType",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "party_type",
+ "fieldtype": "Link",
+ "label": "Party Type",
+ "options": "DocType"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "party",
- "fieldtype": "Dynamic Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Party",
- "length": 0,
- "no_copy": 0,
- "options": "party_type",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "party",
+ "fieldtype": "Dynamic Link",
+ "label": "Party",
+ "options": "party_type"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 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,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_4",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "reference_doctype",
- "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": 1,
- "label": "Reference Doctype",
- "length": 0,
- "no_copy": 1,
- "options": "DocType",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "reference_doctype",
+ "fieldtype": "Link",
+ "in_standard_filter": 1,
+ "label": "Reference Doctype",
+ "no_copy": 1,
+ "options": "DocType",
+ "print_hide": 1,
+ "read_only": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "reference_name",
- "fieldtype": "Dynamic Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 1,
- "in_list_view": 0,
- "in_standard_filter": 1,
- "label": "Reference Name",
- "length": 0,
- "no_copy": 1,
- "options": "reference_doctype",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "reference_name",
+ "fieldtype": "Dynamic Link",
+ "in_global_search": 1,
+ "in_standard_filter": 1,
+ "label": "Reference Name",
+ "no_copy": 1,
+ "options": "reference_doctype",
+ "print_hide": 1,
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "transaction_details",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Transaction Details",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "transaction_details",
+ "fieldtype": "Section Break",
+ "label": "Transaction Details"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "Amount in customer's currency",
- "fieldname": "grand_total",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Amount",
- "length": 0,
- "no_copy": 0,
- "options": "currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "description": "Amount in customer's currency",
+ "fieldname": "grand_total",
+ "fieldtype": "Currency",
+ "label": "Amount",
+ "options": "currency"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "is_a_subscription",
- "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": "Is a Subscription",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "is_a_subscription",
+ "fieldtype": "Check",
+ "label": "Is a Subscription"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_18",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_18",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "currency",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Transaction Currency",
- "length": 0,
- "no_copy": 0,
- "options": "Currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "currency",
+ "fieldtype": "Link",
+ "label": "Transaction Currency",
+ "options": "Currency",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "collapsible_depends_on": "",
- "columns": 0,
- "depends_on": "eval:doc.is_a_subscription",
- "fieldname": "subscription_section",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Subscription Section",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "depends_on": "eval:doc.is_a_subscription",
+ "fieldname": "subscription_section",
+ "fieldtype": "Section Break",
+ "label": "Subscription Section"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "subscription_plans",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Subscription Plans",
- "length": 0,
- "no_copy": 0,
- "options": "Subscription Plan Detail",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "subscription_plans",
+ "fieldtype": "Table",
+ "label": "Subscription Plans",
+ "options": "Subscription Plan Detail"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 1,
- "columns": 0,
- "fieldname": "bank_account_details",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Bank Account Details",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "collapsible": 1,
+ "fieldname": "bank_account_details",
+ "fieldtype": "Section Break",
+ "label": "Bank Account Details"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "bank_account",
- "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": "Bank Account",
- "length": 0,
- "no_copy": 0,
- "options": "Bank Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "bank_account",
+ "fieldtype": "Link",
+ "label": "Bank Account",
+ "options": "Bank Account"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "bank_account.bank",
- "fieldname": "bank",
- "fieldtype": "Read Only",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Bank",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "bank_account.bank",
+ "fieldname": "bank",
+ "fieldtype": "Read Only",
+ "label": "Bank"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "bank_account.bank_account_no",
- "fieldname": "bank_account_no",
- "fieldtype": "Read Only",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Bank Account No",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "bank_account.bank_account_no",
+ "fieldname": "bank_account_no",
+ "fieldtype": "Read Only",
+ "label": "Bank Account No"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "bank_account.account",
- "fieldname": "account",
- "fieldtype": "Read Only",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Account",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "bank_account.account",
+ "fieldname": "account",
+ "fieldtype": "Read Only",
+ "label": "Account"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_11",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_11",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "bank_account.iban",
- "fieldname": "iban",
- "fieldtype": "Read Only",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "IBAN",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "bank_account.iban",
+ "fieldname": "iban",
+ "fieldtype": "Read Only",
+ "label": "IBAN"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "bank.branch_code",
- "fieldname": "branch_code",
- "fieldtype": "Read Only",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Branch Code",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "bank_account.branch_code",
+ "fieldname": "branch_code",
+ "fieldtype": "Read Only",
+ "label": "Branch Code"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "bank.swift_number",
- "fieldname": "swift_number",
- "fieldtype": "Read Only",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "SWIFT Number",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "bank_account.swift_number",
+ "fieldname": "swift_number",
+ "fieldtype": "Read Only",
+ "label": "SWIFT Number"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval: doc.payment_request_type == 'Inward'",
- "fieldname": "recipient_and_message",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Recipient Message And Payment Details",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "depends_on": "eval: doc.payment_request_type == 'Inward'",
+ "fieldname": "recipient_and_message",
+ "fieldtype": "Section Break",
+ "label": "Recipient Message And Payment Details"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "fieldname": "print_format",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Print Format",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "print_format",
+ "fieldtype": "Select",
+ "label": "Print Format"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "email_to",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 1,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "To",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "email_to",
+ "fieldtype": "Data",
+ "in_global_search": 1,
+ "label": "To"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "subject",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 1,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Subject",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "subject",
+ "fieldtype": "Data",
+ "in_global_search": 1,
+ "label": "Subject"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_9",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_9",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval: doc.payment_request_type == 'Inward'",
- "fieldname": "payment_gateway_account",
- "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": "Payment Gateway Account",
- "length": 0,
- "no_copy": 0,
- "options": "Payment Gateway Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "depends_on": "eval: doc.payment_request_type == 'Inward'",
+ "fieldname": "payment_gateway_account",
+ "fieldtype": "Link",
+ "label": "Payment Gateway Account",
+ "options": "Payment Gateway Account"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "Draft",
- "fieldname": "status",
- "fieldtype": "Select",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 1,
- "label": "Status",
- "length": 0,
- "no_copy": 0,
- "options": "\nDraft\nInitiated\nPayment Ordered\nPaid\nFailed\nCancelled",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "Draft",
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "hidden": 1,
+ "in_standard_filter": 1,
+ "label": "Status",
+ "options": "\nDraft\nRequested\nInitiated\nPartially Paid\nPayment Ordered\nPaid\nFailed\nCancelled",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:doc.reference_doctype==\"Sales Order\"",
- "fieldname": "make_sales_invoice",
- "fieldtype": "Check",
- "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": "Make Sales Invoice",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "depends_on": "eval:doc.reference_doctype==\"Sales Order\"",
+ "fieldname": "make_sales_invoice",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "label": "Make Sales Invoice",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval: doc.payment_request_type == 'Inward'",
- "fieldname": "section_break_10",
- "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,
- "translatable": 0,
- "unique": 0
- },
+ "depends_on": "eval: doc.payment_request_type == 'Inward'",
+ "fieldname": "section_break_10",
+ "fieldtype": "Section Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "message",
- "fieldtype": "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": "Message",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "message",
+ "fieldtype": "Text",
+ "label": "Message"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "message_examples",
- "fieldtype": "HTML",
- "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": "Message Examples",
- "length": 0,
- "no_copy": 0,
- "options": "<pre><h5>Message Example</h5>\n\n<p>Dear {{ doc.contact_person }},</p>\n\n<p>Requesting payment for {{ doc.doctype }}, {{ doc.name }} for {{ doc.grand_total }}.</p>\n\n<a href=\"{{ payment_url }}\"> click here to pay </a>\n\n</pre>\n",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "message_examples",
+ "fieldtype": "HTML",
+ "label": "Message Examples",
+ "options": "<pre><h5>Message Example</h5>\n\n<p>Dear {{ doc.contact_person }},</p>\n\n<p>Requesting payment for {{ doc.doctype }}, {{ doc.name }} for {{ doc.grand_total }}.</p>\n\n<a href=\"{{ payment_url }}\"> click here to pay </a>\n\n</pre>\n",
+ "print_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "mute_email",
- "fieldtype": "Check",
- "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": "Mute Email",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "mute_email",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "label": "Mute Email",
+ "no_copy": 1,
+ "print_hide": 1,
+ "read_only": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "payment_url",
- "fieldtype": "Small Text",
- "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": "payment_url",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "payment_url",
+ "fieldtype": "Small Text",
+ "hidden": 1,
+ "label": "payment_url",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 1,
- "collapsible_depends_on": "doc.payment_gateway_account",
- "columns": 0,
- "depends_on": "eval: doc.payment_request_type == 'Inward'",
- "fieldname": "section_break_7",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Payment Gateway Details",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "collapsible": 1,
+ "collapsible_depends_on": "doc.payment_gateway_account",
+ "depends_on": "eval: doc.payment_request_type == 'Inward'",
+ "fieldname": "section_break_7",
+ "fieldtype": "Section Break",
+ "label": "Payment Gateway Details"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "payment_gateway_account.payment_gateway",
- "fieldname": "payment_gateway",
- "fieldtype": "Read Only",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Payment Gateway",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "payment_gateway_account.payment_gateway",
+ "fieldname": "payment_gateway",
+ "fieldtype": "Read Only",
+ "label": "Payment Gateway"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "payment_gateway_account.payment_account",
- "fieldname": "payment_account",
- "fieldtype": "Read Only",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Payment Account",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "payment_gateway_account.payment_account",
+ "fieldname": "payment_account",
+ "fieldtype": "Read Only",
+ "label": "Payment Account",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "payment_order",
- "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": "Payment Order",
- "length": 0,
- "no_copy": 0,
- "options": "Payment Order",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "payment_order",
+ "fieldtype": "Link",
+ "label": "Payment Order",
+ "options": "Payment Order",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 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": "Payment Request",
- "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,
- "translatable": 0,
- "unique": 0
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "label": "Amended From",
+ "no_copy": 1,
+ "options": "Payment Request",
+ "print_hide": 1,
+ "read_only": 1
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 1,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2019-02-18 18:52:34.203239",
- "modified_by": "Administrator",
- "module": "Accounts",
- "name": "Payment Request",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "is_submittable": 1,
+ "modified": "2020-03-28 16:07:31.960798",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Payment Request",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Accounts User",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Accounts User",
+ "share": 1,
"write": 1
- },
+ },
{
- "amend": 1,
- "cancel": 1,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Accounts Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 1,
+ "amend": 1,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Accounts Manager",
+ "share": 1,
+ "submit": 1,
"write": 1
}
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 0,
- "track_seen": 0,
- "track_views": 0
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC"
}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py
index 7e9211a..53ff222 100644
--- a/erpnext/accounts/doctype/payment_request/payment_request.py
+++ b/erpnext/accounts/doctype/payment_request/payment_request.py
@@ -66,6 +66,8 @@
if self.payment_request_type == 'Outward':
self.db_set('status', 'Initiated')
return
+ elif self.payment_request_type == 'Inward':
+ self.db_set('status', 'Requested')
send_mail = self.payment_gateway_validation()
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
@@ -88,6 +90,7 @@
if (hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart"):
from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice
si = make_sales_invoice(self.reference_name, ignore_permissions=True)
+ si.allocate_advances_automatically = True
si = si.insert(ignore_permissions=True)
si.submit()
@@ -415,17 +418,31 @@
doc = frappe.get_doc("Payment Request", docname)
return doc.create_payment_entry(submit=False).as_dict()
-def make_status_as_paid(doc, method):
+def update_payment_req_status(doc, method):
+ from erpnext.accounts.doctype.payment_entry.payment_entry import get_reference_details
+
for ref in doc.references:
payment_request_name = frappe.db.get_value("Payment Request",
{"reference_doctype": ref.reference_doctype, "reference_name": ref.reference_name,
"docstatus": 1})
if payment_request_name:
- doc = frappe.get_doc("Payment Request", payment_request_name)
- if doc.status != "Paid":
- doc.db_set('status', 'Paid')
- frappe.db.commit()
+ ref_details = get_reference_details(ref.reference_doctype, ref.reference_name, doc.party_account_currency)
+ pay_req_doc = frappe.get_doc('Payment Request', payment_request_name)
+ status = pay_req_doc.status
+
+ if status != "Paid" and not ref_details.outstanding_amount:
+ status = 'Paid'
+ elif status != "Partially Paid" and ref_details.outstanding_amount != ref_details.total_amount:
+ status = 'Partially Paid'
+ elif ref_details.outstanding_amount == ref_details.total_amount:
+ if pay_req_doc.payment_request_type == 'Outward':
+ status = 'Initiated'
+ elif pay_req_doc.payment_request_type == 'Inward':
+ status = 'Requested'
+
+ pay_req_doc.db_set('status', status)
+ frappe.db.commit()
def get_dummy_message(doc):
return frappe.render_template("""{% if doc.contact_person -%}
diff --git a/erpnext/accounts/doctype/payment_request/payment_request_list.js b/erpnext/accounts/doctype/payment_request/payment_request_list.js
index 0caf1c2..72833d2 100644
--- a/erpnext/accounts/doctype/payment_request/payment_request_list.js
+++ b/erpnext/accounts/doctype/payment_request/payment_request_list.js
@@ -4,14 +4,20 @@
if(doc.status == "Draft") {
return [__("Draft"), "darkgrey", "status,=,Draft"];
}
+ if(doc.status == "Requested") {
+ return [__("Requested"), "green", "status,=,Requested"];
+ }
else if(doc.status == "Initiated") {
return [__("Initiated"), "green", "status,=,Initiated"];
}
+ else if(doc.status == "Partially Paid") {
+ return [__("Partially Paid"), "orange", "status,=,Partially Paid"];
+ }
else if(doc.status == "Paid") {
return [__("Paid"), "blue", "status,=,Paid"];
}
else if(doc.status == "Cancelled") {
- return [__("Cancelled"), "orange", "status,=,Cancelled"];
+ return [__("Cancelled"), "red", "status,=,Cancelled"];
}
}
}
diff --git a/erpnext/accounts/doctype/payment_request/test_payment_request.py b/erpnext/accounts/doctype/payment_request/test_payment_request.py
index 188ab0a..8a10e2c 100644
--- a/erpnext/accounts/doctype/payment_request/test_payment_request.py
+++ b/erpnext/accounts/doctype/payment_request/test_payment_request.py
@@ -101,6 +101,23 @@
self.assertEqual(expected_gle[gle.account][2], gle.credit)
self.assertEqual(expected_gle[gle.account][3], gle.against_voucher)
+ def test_status(self):
+ si_usd = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
+ currency="USD", conversion_rate=50)
+
+ pr = make_payment_request(dt="Sales Invoice", dn=si_usd.name, recipient_id="saurabh@erpnext.com",
+ mute_email=1, payment_gateway="_Test Gateway - USD", submit_doc=1, return_doc=1)
+
+ pe = pr.create_payment_entry()
+ pr.load_from_db()
+
+ self.assertEqual(pr.status, 'Paid')
+
+ pe.cancel()
+ pr.load_from_db()
+
+ self.assertEqual(pr.status, 'Requested')
+
def test_multiple_payment_entries_against_sales_order(self):
# Make Sales Order, grand_total = 1000
so = make_sales_order()
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index db6ac55..6f78db2 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -794,7 +794,7 @@
},
refresh: function(frm) {
- if (frappe.boot.active_domains.includes("Healthcare")){
+ if (frappe.boot.active_domains.includes("Healthcare")) {
frm.set_df_property("patient", "hidden", 0);
frm.set_df_property("patient_name", "hidden", 0);
frm.set_df_property("ref_practitioner", "hidden", 0);
@@ -807,7 +807,7 @@
},"Get items from");
}
}
- else{
+ else {
frm.set_df_property("patient", "hidden", 1);
frm.set_df_property("patient_name", "hidden", 1);
frm.set_df_property("ref_practitioner", "hidden", 1);
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 3d5ce8a..0e54b62 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -1926,6 +1926,16 @@
item.taxes = []
item.save()
+ def test_customer_provided_parts_si(self):
+ create_item('CUST-0987', is_customer_provided_item = 1, customer = '_Test Customer', is_purchase_item = 0)
+ si = create_sales_invoice(item_code='CUST-0987', rate=0)
+ self.assertEqual(si.get("items")[0].allow_zero_valuation_rate, 1)
+ self.assertEqual(si.get("items")[0].amount, 0)
+
+ # test if Sales Invoice with rate is allowed
+ si2 = create_sales_invoice(item_code='CUST-0987', do_not_save=True)
+ self.assertRaises(frappe.ValidationError, si2.save)
+
def create_sales_invoice(**args):
si = frappe.new_doc("Sales Invoice")
args = frappe._dict(args)
@@ -1948,7 +1958,7 @@
"gst_hsn_code": "999800",
"warehouse": args.warehouse or "_Test Warehouse - _TC",
"qty": args.qty or 1,
- "rate": args.rate or 100,
+ "rate": args.rate if args.get("rate") is not None else 100,
"income_account": args.income_account or "Sales - _TC",
"expense_account": args.expense_account or "Cost of Goods Sold - _TC",
"cost_center": args.cost_center or "_Test Cost Center - _TC",
diff --git a/erpnext/accounts/doctype/shipping_rule/shipping_rule.py b/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
index 1fd340c..b2638c7 100644
--- a/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
+++ b/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
@@ -82,7 +82,7 @@
if not shipping_country:
frappe.throw(_('Shipping Address does not have country, which is required for this Shipping Rule'))
if shipping_country not in [d.country for d in self.countries]:
- frappe.throw(_('Shipping rule not applicable for country {0}').format(shipping_country))
+ frappe.throw(_('Shipping rule not applicable for country {0} in Shipping Address').format(shipping_country))
def add_shipping_rule_to_tax_table(self, doc, shipping_amount):
shipping_charge = {
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index 4cfeb25..47dfa09 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -162,8 +162,9 @@
def set_price_list(party_details, party, party_type, given_price_list, pos=None):
# price list
price_list = get_permitted_documents('Price List')
-
- if price_list:
+
+ # if there is only one permitted document based on user permissions, set it
+ if price_list and len(price_list) == 1:
price_list = price_list[0]
elif pos and party_type == 'Customer':
customer_price_list = frappe.get_value('Customer', party.name, 'default_price_list')
@@ -635,4 +636,4 @@
except:
return None
else:
- return None
\ No newline at end of file
+ return None
diff --git a/erpnext/accounts/report/balance_sheet/balance_sheet.py b/erpnext/accounts/report/balance_sheet/balance_sheet.py
index cb1fdc1..a858c19 100644
--- a/erpnext/accounts/report/balance_sheet/balance_sheet.py
+++ b/erpnext/accounts/report/balance_sheet/balance_sheet.py
@@ -9,6 +9,7 @@
def execute(filters=None):
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
+ filters.period_start_date, filters.period_end_date, filters.filter_based_on,
filters.periodicity, company=filters.company)
currency = filters.presentation_currency or frappe.get_cached_value('Company', filters.company, "default_currency")
diff --git a/erpnext/accounts/report/cash_flow/cash_flow.js b/erpnext/accounts/report/cash_flow/cash_flow.js
index 904874f..e5d0c89 100644
--- a/erpnext/accounts/report/cash_flow/cash_flow.js
+++ b/erpnext/accounts/report/cash_flow/cash_flow.js
@@ -9,7 +9,7 @@
// filter. It won't be used in cash flow for now so we pop it. Please take
// of this if you are working here.
- frappe.query_reports["Cash Flow"]["filters"].splice(5, 1);
+ frappe.query_reports["Cash Flow"]["filters"].splice(8, 1);
frappe.query_reports["Cash Flow"]["filters"].push(
{
diff --git a/erpnext/accounts/report/cash_flow/cash_flow.py b/erpnext/accounts/report/cash_flow/cash_flow.py
index be6e93c..cf0946b 100644
--- a/erpnext/accounts/report/cash_flow/cash_flow.py
+++ b/erpnext/accounts/report/cash_flow/cash_flow.py
@@ -17,7 +17,8 @@
return execute_custom(filters=filters)
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
- filters.periodicity, filters.accumulated_values, filters.company)
+ filters.period_start_date, filters.period_end_date, filters.filter_based_on,
+ filters.periodicity, company=filters.company)
cash_flow_accounts = get_cash_flow_accounts()
diff --git a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js
index 92c5ee9..38fd5fa 100644
--- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js
+++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js
@@ -13,6 +13,39 @@
"reqd": 1
},
{
+ "fieldname":"filter_based_on",
+ "label": __("Filter Based On"),
+ "fieldtype": "Select",
+ "options": ["Fiscal Year", "Date Range"],
+ "default": ["Fiscal Year"],
+ "reqd": 1,
+ on_change: function() {
+ let filter_based_on = frappe.query_report.get_filter_value('filter_based_on');
+ frappe.query_report.toggle_filter_display('from_fiscal_year', filter_based_on === 'Date Range');
+ frappe.query_report.toggle_filter_display('to_fiscal_year', filter_based_on === 'Date Range');
+ frappe.query_report.toggle_filter_display('period_start_date', filter_based_on === 'Fiscal Year');
+ frappe.query_report.toggle_filter_display('period_end_date', filter_based_on === 'Fiscal Year');
+
+ frappe.query_report.refresh();
+ }
+ },
+ {
+ "fieldname":"period_start_date",
+ "label": __("Start Date"),
+ "fieldtype": "Date",
+ "default": frappe.datetime.nowdate(),
+ "hidden": 1,
+ "reqd": 1
+ },
+ {
+ "fieldname":"period_end_date",
+ "label": __("End Date"),
+ "fieldtype": "Date",
+ "default": frappe.datetime.add_months(frappe.datetime.nowdate(), 12),
+ "hidden": 1,
+ "reqd": 1
+ },
+ {
"fieldname":"from_fiscal_year",
"label": __("Start Year"),
"fieldtype": "Link",
diff --git a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
index 461291b..b62238b 100644
--- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
+++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import frappe, erpnext
from frappe import _
-from frappe.utils import flt, cint
+from frappe.utils import flt, cint, getdate
from erpnext.accounts.report.utils import get_currency, convert_to_presentation_currency
from erpnext.accounts.report.financial_statements import get_fiscal_year_data, sort_accounts
from erpnext.accounts.report.balance_sheet.balance_sheet import (get_provisional_profit_loss,
@@ -208,17 +208,24 @@
company_currency = get_company_currency(filters)
+ if filters.filter_based_on == 'Fiscal Year':
+ start_date = fiscal_year.year_start_date
+ end_date = fiscal_year.year_end_date
+ else:
+ start_date = filters.period_start_date
+ end_date = filters.period_end_date
+
gl_entries_by_account = {}
for root in frappe.db.sql("""select lft, rgt from tabAccount
where root_type=%s and ifnull(parent_account, '') = ''""", root_type, as_dict=1):
- set_gl_entries_by_account(fiscal_year.year_start_date,
- fiscal_year.year_end_date, root.lft, root.rgt, filters,
+ set_gl_entries_by_account(start_date,
+ end_date, root.lft, root.rgt, filters,
gl_entries_by_account, accounts_by_name, ignore_closing_entries=False)
- calculate_values(accounts_by_name, gl_entries_by_account, companies, fiscal_year, filters)
+ calculate_values(accounts_by_name, gl_entries_by_account, companies, start_date, filters)
accumulate_values_into_parents(accounts, accounts_by_name, companies)
- out = prepare_data(accounts, fiscal_year, balance_must_be, companies, company_currency)
+ out = prepare_data(accounts, start_date, end_date, balance_must_be, companies, company_currency)
if out:
add_total_row(out, root_type, balance_must_be, companies, company_currency)
@@ -229,7 +236,7 @@
return (filters.get('presentation_currency')
or frappe.get_cached_value('Company', filters.company, "default_currency"))
-def calculate_values(accounts_by_name, gl_entries_by_account, companies, fiscal_year, filters):
+def calculate_values(accounts_by_name, gl_entries_by_account, companies, start_date, filters):
for entries in gl_entries_by_account.values():
for entry in entries:
key = entry.account_number or entry.account_name
@@ -241,7 +248,7 @@
and entry.company in companies.get(company)):
d[company] = d.get(company, 0.0) + flt(entry.debit) - flt(entry.credit)
- if entry.posting_date < fiscal_year.year_start_date:
+ if entry.posting_date < getdate(start_date):
d["opening_balance"] = d.get("opening_balance", 0.0) + flt(entry.debit) - flt(entry.credit)
def accumulate_values_into_parents(accounts, accounts_by_name, companies):
@@ -295,10 +302,8 @@
`tabAccount` where company = %s and root_type = %s
""" , (filters.get('company'), root_type), as_dict=1)
-def prepare_data(accounts, fiscal_year, balance_must_be, companies, company_currency):
+def prepare_data(accounts, start_date, end_date, balance_must_be, companies, company_currency):
data = []
- year_start_date = fiscal_year.year_start_date
- year_end_date = fiscal_year.year_end_date
for d in accounts:
# add to output
@@ -309,8 +314,8 @@
"account": _(d.account_name),
"parent_account": _(d.parent_account),
"indent": flt(d.indent),
- "year_start_date": year_start_date,
- "year_end_date": year_end_date,
+ "year_start_date": start_date,
+ "year_end_date": end_date,
"currency": company_currency,
"opening_balance": d.get("opening_balance", 0.0) * (1 if balance_must_be == "Debit" else -1)
})
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index e760b79..7fb598b 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -18,17 +18,20 @@
from six import itervalues
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
-def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_values=False,
+def get_period_list(from_fiscal_year, to_fiscal_year, period_start_date, period_end_date, filter_based_on, periodicity, accumulated_values=False,
company=None, reset_period_on_fy_change=True):
"""Get a list of dict {"from_date": from_date, "to_date": to_date, "key": key, "label": label}
Periodicity can be (Yearly, Quarterly, Monthly)"""
- fiscal_year = get_fiscal_year_data(from_fiscal_year, to_fiscal_year)
- validate_fiscal_year(fiscal_year, from_fiscal_year, to_fiscal_year)
-
- # start with first day, so as to avoid year to_dates like 2-April if ever they occur]
- year_start_date = getdate(fiscal_year.year_start_date)
- year_end_date = getdate(fiscal_year.year_end_date)
+ if filter_based_on == 'Fiscal Year':
+ fiscal_year = get_fiscal_year_data(from_fiscal_year, to_fiscal_year)
+ validate_fiscal_year(fiscal_year, from_fiscal_year, to_fiscal_year)
+ year_start_date = getdate(fiscal_year.year_start_date)
+ year_end_date = getdate(fiscal_year.year_end_date)
+ else:
+ validate_dates(period_start_date, period_end_date)
+ year_start_date = getdate(period_start_date)
+ year_end_date = getdate(period_end_date)
months_to_add = {
"Yearly": 12,
@@ -42,6 +45,9 @@
start_date = year_start_date
months = get_months(year_start_date, year_end_date)
+ if (months // months_to_add) != (months / months_to_add):
+ months += months_to_add
+
for i in range(months // months_to_add):
period = frappe._dict({
"from_date": start_date
@@ -103,9 +109,18 @@
def validate_fiscal_year(fiscal_year, from_fiscal_year, to_fiscal_year):
- if not fiscal_year.get('year_start_date') and not fiscal_year.get('year_end_date'):
+ if not fiscal_year.get('year_start_date') or not fiscal_year.get('year_end_date'):
+ frappe.throw(_("Start Year and End Year are mandatory"))
+
+ if getdate(fiscal_year.get('year_end_date')) < getdate(fiscal_year.get('year_start_date')):
frappe.throw(_("End Year cannot be before Start Year"))
+def validate_dates(from_date, to_date):
+ if not from_date or not to_date:
+ frappe.throw("From Date and To Date are mandatory")
+
+ if to_date < from_date:
+ frappe.throw("To Date cannot be less than From Date")
def get_months(start_date, end_date):
diff = (12 * end_date.year + end_date.month) - (12 * start_date.year + start_date.month)
@@ -419,7 +434,9 @@
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
filters.get(dimension.fieldname))
- additional_conditions.append("{0} in %({0})s".format(dimension.fieldname))
+ additional_conditions.append("{0} in %({0})s".format(dimension.fieldname))
+ else:
+ additional_conditions.append("{0} in (%({0})s)".format(dimension.fieldname))
return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else ""
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py
index 898ac13..649b363 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.py
+++ b/erpnext/accounts/report/general_ledger/general_ledger.py
@@ -202,7 +202,9 @@
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
filters.get(dimension.fieldname))
- conditions.append("{0} in %({0})s".format(dimension.fieldname))
+ conditions.append("{0} in %({0})s".format(dimension.fieldname))
+ else:
+ conditions.append("{0} in (%({0})s)".format(dimension.fieldname))
return "and {}".format(" and ".join(conditions)) if conditions else ""
diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py
index 81fb1e0..7caa764 100644
--- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py
+++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py
@@ -9,7 +9,8 @@
def execute(filters=None):
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
- filters.periodicity, filters.accumulated_values, filters.company)
+ filters.period_start_date, filters.period_end_date, filters.filter_based_on, filters.periodicity,
+ company=filters.company)
income = get_data(filters.company, "Income", "Credit", period_list, filters = filters,
accumulated_values=filters.accumulated_values,
diff --git a/erpnext/accounts/report/purchase_register/purchase_register.js b/erpnext/accounts/report/purchase_register/purchase_register.js
index 42b35c2..b2b95b2 100644
--- a/erpnext/accounts/report/purchase_register/purchase_register.js
+++ b/erpnext/accounts/report/purchase_register/purchase_register.js
@@ -34,6 +34,33 @@
"label": __("Mode of Payment"),
"fieldtype": "Link",
"options": "Mode of Payment"
+ },
+ {
+ "fieldname":"cost_center",
+ "label": __("Cost Center"),
+ "fieldtype": "Link",
+ "options": "Cost Center"
+ },
+ {
+ "fieldname":"warehouse",
+ "label": __("Warehouse"),
+ "fieldtype": "Link",
+ "options": "Warehouse"
+ },
+ {
+ "fieldname":"item_group",
+ "label": __("Item Group"),
+ "fieldtype": "Link",
+ "options": "Item Group"
}
]
}
+
+erpnext.dimension_filters.forEach((dimension) => {
+ frappe.query_reports["Purchase Register"].filters.splice(7, 0 ,{
+ "fieldname": dimension["fieldname"],
+ "label": __(dimension["label"]),
+ "fieldtype": "Link",
+ "options": dimension["document_type"]
+ });
+});
\ No newline at end of file
diff --git a/erpnext/accounts/report/purchase_register/purchase_register.py b/erpnext/accounts/report/purchase_register/purchase_register.py
index 3f8abb7..9399e70 100644
--- a/erpnext/accounts/report/purchase_register/purchase_register.py
+++ b/erpnext/accounts/report/purchase_register/purchase_register.py
@@ -5,6 +5,7 @@
import frappe
from frappe.utils import flt
from frappe import msgprint, _
+from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
def execute(filters=None):
return _execute(filters)
@@ -66,7 +67,7 @@
total_tax += tax_amount
row.append(tax_amount)
- # total tax, grand total, rounded total & outstanding amount
+ # total tax, grand total, rounded total & outstanding amount
row += [total_tax, inv.base_grand_total, flt(inv.base_grand_total, 0), inv.outstanding_amount]
data.append(row)
@@ -134,6 +135,38 @@
if filters.get("mode_of_payment"): conditions += " and ifnull(mode_of_payment, '') = %(mode_of_payment)s"
+ if filters.get("cost_center"):
+ conditions += """ and exists(select name from `tabPurchase Invoice Item`
+ where parent=`tabPurchase Invoice`.name
+ and ifnull(`tabPurchase Invoice Item`.cost_center, '') = %(cost_center)s)"""
+
+ if filters.get("warehouse"):
+ conditions += """ and exists(select name from `tabPurchase Invoice Item`
+ where parent=`tabPurchase Invoice`.name
+ and ifnull(`tabPurchase Invoice Item`.warehouse, '') = %(warehouse)s)"""
+
+ if filters.get("item_group"):
+ conditions += """ and exists(select name from `tabPurchase Invoice Item`
+ where parent=`tabPurchase Invoice`.name
+ and ifnull(`tabPurchase Invoice Item`.item_group, '') = %(item_group)s)"""
+
+ accounting_dimensions = get_accounting_dimensions(as_list=False)
+
+ if accounting_dimensions:
+ common_condition = """
+ and exists(select name from `tabPurchase Invoice Item`
+ where parent=`tabPurchase Invoice`.name
+ """
+ for dimension in accounting_dimensions:
+ if filters.get(dimension.fieldname):
+ if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
+ filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
+ filters.get(dimension.fieldname))
+
+ conditions += common_condition + "and ifnull(`tabPurchase Invoice Item`.{0}, '') in %({0})s)".format(dimension.fieldname)
+ else:
+ conditions += common_condition + "and ifnull(`tabPurchase Invoice Item`.{0}, '') in (%({0})s))".format(dimension.fieldname)
+
return conditions
def get_invoices(filters, additional_query_columns):
diff --git a/erpnext/accounts/report/sales_register/sales_register.py b/erpnext/accounts/report/sales_register/sales_register.py
index 9864e40..b6e61b1 100644
--- a/erpnext/accounts/report/sales_register/sales_register.py
+++ b/erpnext/accounts/report/sales_register/sales_register.py
@@ -344,16 +344,19 @@
accounting_dimensions = get_accounting_dimensions(as_list=False)
if accounting_dimensions:
+ common_condition = """
+ and exists(select name from `tabSales Invoice Item`
+ where parent=`tabSales Invoice`.name
+ """
for dimension in accounting_dimensions:
if filters.get(dimension.fieldname):
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
filters.get(dimension.fieldname))
- conditions += """ and exists(select name from `tabSales Invoice Item`
- where parent=`tabSales Invoice`.name
- and ifnull(`tabSales Invoice Item`.{0}, '') in %({0})s)""".format(dimension.fieldname)
-
+ conditions += common_condition + "and ifnull(`tabSales Invoice Item`.{0}, '') in %({0})s)".format(dimension.fieldname)
+ else:
+ conditions += common_condition + "and ifnull(`tabSales Invoice Item`.{0}, '') in (%({0})s))".format(dimension.fieldname)
return conditions
diff --git a/erpnext/accounts/report/trial_balance/trial_balance.py b/erpnext/accounts/report/trial_balance/trial_balance.py
index 5fe6b41..d783241 100644
--- a/erpnext/accounts/report/trial_balance/trial_balance.py
+++ b/erpnext/accounts/report/trial_balance/trial_balance.py
@@ -126,7 +126,9 @@
if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'):
filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type,
filters.get(dimension.fieldname))
- additional_conditions += "and {0} in %({0})s".format(dimension.fieldname)
+ additional_conditions += "and {0} in %({0})s".format(dimension.fieldname)
+ else:
+ additional_conditions += "and {0} in (%({0})s)".format(dimension.fieldname)
query_filters.update({
dimension.fieldname: filters.get(dimension.fieldname)
diff --git a/erpnext/agriculture/desk_page/agriculture/agriculture.json b/erpnext/agriculture/desk_page/agriculture/agriculture.json
index 6020d62..e0d2c9c 100644
--- a/erpnext/agriculture/desk_page/agriculture/agriculture.json
+++ b/erpnext/agriculture/desk_page/agriculture/agriculture.json
@@ -1,16 +1,19 @@
{
"cards": [
{
- "links": "[\n {\n \"label\": \"Crop\",\n \"name\": \"Crop\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Crop Cycle\",\n \"name\": \"Crop Cycle\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Location\",\n \"name\": \"Location\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]",
- "title": "Crops & Lands"
+ "hidden": 0,
+ "label": "Crops & Lands",
+ "links": "[\n {\n \"label\": \"Crop\",\n \"name\": \"Crop\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Crop Cycle\",\n \"name\": \"Crop Cycle\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Location\",\n \"name\": \"Location\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Plant Analysis\",\n \"name\": \"Plant Analysis\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Soil Analysis\",\n \"name\": \"Soil Analysis\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Water Analysis\",\n \"name\": \"Water Analysis\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Soil Texture\",\n \"name\": \"Soil Texture\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Weather\",\n \"name\": \"Weather\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Agriculture Analysis Criteria\",\n \"name\": \"Agriculture Analysis Criteria\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Analytics"
+ "hidden": 0,
+ "label": "Analytics",
+ "links": "[\n {\n \"label\": \"Plant Analysis\",\n \"name\": \"Plant Analysis\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Soil Analysis\",\n \"name\": \"Soil Analysis\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Water Analysis\",\n \"name\": \"Water Analysis\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Soil Texture\",\n \"name\": \"Soil Texture\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Weather\",\n \"name\": \"Weather\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Agriculture Analysis Criteria\",\n \"name\": \"Agriculture Analysis Criteria\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Disease\",\n \"name\": \"Disease\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Fertilizer\",\n \"name\": \"Fertilizer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]",
- "title": "Diseases & Fertilizers"
+ "hidden": 0,
+ "label": "Diseases & Fertilizers",
+ "links": "[\n {\n \"label\": \"Disease\",\n \"name\": \"Disease\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Fertilizer\",\n \"name\": \"Fertilizer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]"
}
],
"category": "Domains",
@@ -24,7 +27,7 @@
"idx": 0,
"is_standard": 1,
"label": "Agriculture",
- "modified": "2020-03-12 16:30:37.565413",
+ "modified": "2020-04-01 11:28:51.032822",
"modified_by": "Administrator",
"module": "Agriculture",
"name": "Agriculture",
diff --git a/erpnext/assets/desk_page/assets/assets.json b/erpnext/assets/desk_page/assets/assets.json
index f9c65cb..0309416 100644
--- a/erpnext/assets/desk_page/assets/assets.json
+++ b/erpnext/assets/desk_page/assets/assets.json
@@ -1,17 +1,19 @@
{
"cards": [
{
- "links": "[\n {\n \"label\": \"Asset\",\n \"name\": \"Asset\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Location\",\n \"name\": \"Location\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Asset Category\",\n \"name\": \"Asset Category\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Transfer an asset from one warehouse to another\",\n \"label\": \"Asset Movement\",\n \"name\": \"Asset Movement\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Assets"
+ "hidden": 0,
+ "label": "Assets",
+ "links": "[\n {\n \"label\": \"Asset\",\n \"name\": \"Asset\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Location\",\n \"name\": \"Location\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Asset Category\",\n \"name\": \"Asset Category\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Transfer an asset from one warehouse to another\",\n \"label\": \"Asset Movement\",\n \"name\": \"Asset Movement\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Asset Maintenance Team\",\n \"name\": \"Asset Maintenance Team\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Asset Maintenance Team\"\n ],\n \"label\": \"Asset Maintenance\",\n \"name\": \"Asset Maintenance\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Asset Maintenance\"\n ],\n \"label\": \"Asset Maintenance Log\",\n \"name\": \"Asset Maintenance Log\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Asset\"\n ],\n \"label\": \"Asset Value Adjustment\",\n \"name\": \"Asset Value Adjustment\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Asset\"\n ],\n \"label\": \"Asset Repair\",\n \"name\": \"Asset Repair\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Maintenance"
+ "hidden": 0,
+ "label": "Maintenance",
+ "links": "[\n {\n \"label\": \"Asset Maintenance Team\",\n \"name\": \"Asset Maintenance Team\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Asset Maintenance Team\"\n ],\n \"label\": \"Asset Maintenance\",\n \"name\": \"Asset Maintenance\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Asset Maintenance\"\n ],\n \"label\": \"Asset Maintenance Log\",\n \"name\": \"Asset Maintenance Log\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Asset\"\n ],\n \"label\": \"Asset Value Adjustment\",\n \"name\": \"Asset Value Adjustment\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Asset\"\n ],\n \"label\": \"Asset Repair\",\n \"name\": \"Asset Repair\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-table",
- "links": "[\n {\n \"dependencies\": [\n \"Asset\"\n ],\n \"doctype\": \"Asset\",\n \"is_query_report\": true,\n \"label\": \"Asset Depreciation Ledger\",\n \"name\": \"Asset Depreciation Ledger\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Asset\"\n ],\n \"doctype\": \"Asset\",\n \"is_query_report\": true,\n \"label\": \"Asset Depreciations and Balances\",\n \"name\": \"Asset Depreciations and Balances\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Asset Maintenance\"\n ],\n \"doctype\": \"Asset Maintenance\",\n \"label\": \"Asset Maintenance\",\n \"name\": \"Asset Maintenance\",\n \"type\": \"report\"\n }\n]",
- "title": "Reports"
+ "hidden": 0,
+ "label": "Reports",
+ "links": "[\n {\n \"dependencies\": [\n \"Asset\"\n ],\n \"doctype\": \"Asset\",\n \"is_query_report\": true,\n \"label\": \"Asset Depreciation Ledger\",\n \"name\": \"Asset Depreciation Ledger\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Asset\"\n ],\n \"doctype\": \"Asset\",\n \"is_query_report\": true,\n \"label\": \"Asset Depreciations and Balances\",\n \"name\": \"Asset Depreciations and Balances\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Asset Maintenance\"\n ],\n \"doctype\": \"Asset Maintenance\",\n \"label\": \"Asset Maintenance\",\n \"name\": \"Asset Maintenance\",\n \"type\": \"report\"\n }\n]"
}
],
"category": "Modules",
@@ -26,7 +28,7 @@
"idx": 0,
"is_standard": 1,
"label": "Assets",
- "modified": "2020-03-12 16:30:38.651019",
+ "modified": "2020-04-01 11:28:51.072198",
"modified_by": "Administrator",
"module": "Assets",
"name": "Assets",
@@ -35,17 +37,17 @@
"pin_to_top": 0,
"shortcuts": [
{
- "is_query_report": 0,
+ "label": "Asset",
"link_to": "Asset",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Asset Movement",
"link_to": "Asset Movement",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Fixed Asset Register",
"link_to": "Fixed Asset Register",
"type": "Report"
}
diff --git a/erpnext/buying/desk_page/buying/buying.json b/erpnext/buying/desk_page/buying/buying.json
index ae8a605..5e764cf 100644
--- a/erpnext/buying/desk_page/buying/buying.json
+++ b/erpnext/buying/desk_page/buying/buying.json
@@ -1,44 +1,46 @@
{
"cards": [
{
- "links": "[\n {\n \"description\": \"Supplier database.\",\n \"label\": \"Supplier\",\n \"name\": \"Supplier\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Supplier Group master.\",\n \"label\": \"Supplier Group\",\n \"name\": \"Supplier Group\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Contacts.\",\n \"label\": \"Contact\",\n \"name\": \"Contact\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Addresses.\",\n \"label\": \"Address\",\n \"name\": \"Address\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Supplier"
+ "hidden": 0,
+ "label": "Supplier",
+ "links": "[\n {\n \"description\": \"Supplier database.\",\n \"label\": \"Supplier\",\n \"name\": \"Supplier\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Supplier Group master.\",\n \"label\": \"Supplier Group\",\n \"name\": \"Supplier Group\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Contacts.\",\n \"label\": \"Contact\",\n \"name\": \"Contact\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Addresses.\",\n \"label\": \"Address\",\n \"name\": \"Address\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-star",
- "links": "[\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"description\": \"Purchase Orders given to Suppliers.\",\n \"label\": \"Purchase Order\",\n \"name\": \"Purchase Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"label\": \"Purchase Invoice\",\n \"name\": \"Purchase Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Request for purchase.\",\n \"label\": \"Material Request\",\n \"name\": \"Material Request\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"description\": \"Request for quotation.\",\n \"label\": \"Request for Quotation\",\n \"name\": \"Request for Quotation\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"description\": \"Quotations received from Suppliers.\",\n \"label\": \"Supplier Quotation\",\n \"name\": \"Supplier Quotation\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Purchasing"
+ "hidden": 0,
+ "label": "Purchasing",
+ "links": "[\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"description\": \"Purchase Orders given to Suppliers.\",\n \"label\": \"Purchase Order\",\n \"name\": \"Purchase Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"label\": \"Purchase Invoice\",\n \"name\": \"Purchase Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Request for purchase.\",\n \"label\": \"Material Request\",\n \"name\": \"Material Request\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"description\": \"Request for quotation.\",\n \"label\": \"Request for Quotation\",\n \"name\": \"Request for Quotation\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"description\": \"Quotations received from Suppliers.\",\n \"label\": \"Supplier Quotation\",\n \"name\": \"Supplier Quotation\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"All Products or Services.\",\n \"label\": \"Item\",\n \"name\": \"Item\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Multiple Item prices.\",\n \"label\": \"Item Price\",\n \"name\": \"Item Price\",\n \"onboard\": 1,\n \"route\": \"#Report/Item Price\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Price List master.\",\n \"label\": \"Price List\",\n \"name\": \"Price List\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bundle items at time of sale.\",\n \"label\": \"Product Bundle\",\n \"name\": \"Product Bundle\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tree of Item Groups.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Item Group\",\n \"link\": \"Tree/Item Group\",\n \"name\": \"Item Group\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Rules for applying different promotional schemes.\",\n \"label\": \"Promotional Scheme\",\n \"name\": \"Promotional Scheme\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Rules for applying pricing and discount.\",\n \"label\": \"Pricing Rule\",\n \"name\": \"Pricing Rule\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Items and Pricing"
+ "hidden": 0,
+ "label": "Items and Pricing",
+ "links": "[\n {\n \"description\": \"All Products or Services.\",\n \"label\": \"Item\",\n \"name\": \"Item\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Multiple Item prices.\",\n \"label\": \"Item Price\",\n \"name\": \"Item Price\",\n \"onboard\": 1,\n \"route\": \"#Report/Item Price\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Price List master.\",\n \"label\": \"Price List\",\n \"name\": \"Price List\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bundle items at time of sale.\",\n \"label\": \"Product Bundle\",\n \"name\": \"Product Bundle\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tree of Item Groups.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Item Group\",\n \"link\": \"Tree/Item Group\",\n \"name\": \"Item Group\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Rules for applying different promotional schemes.\",\n \"label\": \"Promotional Scheme\",\n \"name\": \"Promotional Scheme\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Rules for applying pricing and discount.\",\n \"label\": \"Pricing Rule\",\n \"name\": \"Pricing Rule\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-cog",
- "links": "[\n {\n \"description\": \"Default settings for buying transactions.\",\n \"label\": \"Buying Settings\",\n \"name\": \"Buying Settings\",\n \"settings\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax template for buying transactions.\",\n \"label\": \"Purchase Taxes and Charges Template\",\n \"name\": \"Purchase Taxes and Charges Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Template of terms or contract.\",\n \"label\": \"Terms and Conditions Template\",\n \"name\": \"Terms and Conditions\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Settings"
+ "hidden": 0,
+ "label": "Settings",
+ "links": "[\n {\n \"description\": \"Default settings for buying transactions.\",\n \"label\": \"Buying Settings\",\n \"name\": \"Buying Settings\",\n \"settings\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax template for buying transactions.\",\n \"label\": \"Purchase Taxes and Charges Template\",\n \"name\": \"Purchase Taxes and Charges Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Template of terms or contract.\",\n \"label\": \"Terms and Conditions Template\",\n \"name\": \"Terms and Conditions\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"All Supplier scorecards.\",\n \"label\": \"Supplier Scorecard\",\n \"name\": \"Supplier Scorecard\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Templates of supplier scorecard variables.\",\n \"label\": \"Supplier Scorecard Variable\",\n \"name\": \"Supplier Scorecard Variable\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Templates of supplier scorecard criteria.\",\n \"label\": \"Supplier Scorecard Criteria\",\n \"name\": \"Supplier Scorecard Criteria\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Templates of supplier standings.\",\n \"label\": \"Supplier Scorecard Standing\",\n \"name\": \"Supplier Scorecard Standing\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Supplier Scorecard"
+ "hidden": 0,
+ "label": "Supplier Scorecard",
+ "links": "[\n {\n \"description\": \"All Supplier scorecards.\",\n \"label\": \"Supplier Scorecard\",\n \"name\": \"Supplier Scorecard\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Templates of supplier scorecard variables.\",\n \"label\": \"Supplier Scorecard Variable\",\n \"name\": \"Supplier Scorecard Variable\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Templates of supplier scorecard criteria.\",\n \"label\": \"Supplier Scorecard Criteria\",\n \"name\": \"Supplier Scorecard Criteria\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Templates of supplier standings.\",\n \"label\": \"Supplier Scorecard Standing\",\n \"name\": \"Supplier Scorecard Standing\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-table",
- "links": "[\n {\n \"is_query_report\": true,\n \"label\": \"Purchase Analytics\",\n \"name\": \"Purchase Analytics\",\n \"onboard\": 1,\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Supplier-Wise Sales Analytics\",\n \"name\": \"Supplier-Wise Sales Analytics\",\n \"onboard\": 1,\n \"reference_doctype\": \"Stock Ledger Entry\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Purchase Order Trends\",\n \"name\": \"Purchase Order Trends\",\n \"onboard\": 1,\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Procurement Tracker\",\n \"name\": \"Procurement Tracker\",\n \"onboard\": 1,\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Requested Items To Be Ordered\",\n \"name\": \"Requested Items To Be Ordered\",\n \"onboard\": 1,\n \"reference_doctype\": \"Material Request\",\n \"type\": \"report\"\n }\n]",
- "title": "Key Reports"
+ "hidden": 0,
+ "label": "Key Reports",
+ "links": "[\n {\n \"is_query_report\": true,\n \"label\": \"Purchase Analytics\",\n \"name\": \"Purchase Analytics\",\n \"onboard\": 1,\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Supplier-Wise Sales Analytics\",\n \"name\": \"Supplier-Wise Sales Analytics\",\n \"onboard\": 1,\n \"reference_doctype\": \"Stock Ledger Entry\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Purchase Order Trends\",\n \"name\": \"Purchase Order Trends\",\n \"onboard\": 1,\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Procurement Tracker\",\n \"name\": \"Procurement Tracker\",\n \"onboard\": 1,\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Requested Items To Be Ordered\",\n \"name\": \"Requested Items To Be Ordered\",\n \"onboard\": 1,\n \"reference_doctype\": \"Material Request\",\n \"type\": \"report\"\n }\n]"
},
{
- "icon": "fa fa-list",
- "links": "[\n {\n \"is_query_report\": true,\n \"label\": \"Items To Be Requested\",\n \"name\": \"Items To Be Requested\",\n \"onboard\": 1,\n \"reference_doctype\": \"Item\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Item-wise Purchase History\",\n \"name\": \"Item-wise Purchase History\",\n \"onboard\": 1,\n \"reference_doctype\": \"Item\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Material Requests for which Supplier Quotations are not created\",\n \"name\": \"Material Requests for which Supplier Quotations are not created\",\n \"reference_doctype\": \"Material Request\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Supplier Addresses And Contacts\",\n \"name\": \"Address And Contacts\",\n \"reference_doctype\": \"Address\",\n \"route_options\": {\n \"party_type\": \"Supplier\"\n },\n \"type\": \"report\"\n }\n]",
- "title": "Other Reports"
+ "hidden": 0,
+ "label": "Other Reports",
+ "links": "[\n {\n \"is_query_report\": true,\n \"label\": \"Items To Be Requested\",\n \"name\": \"Items To Be Requested\",\n \"onboard\": 1,\n \"reference_doctype\": \"Item\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Item-wise Purchase History\",\n \"name\": \"Item-wise Purchase History\",\n \"onboard\": 1,\n \"reference_doctype\": \"Item\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Material Requests for which Supplier Quotations are not created\",\n \"name\": \"Material Requests for which Supplier Quotations are not created\",\n \"reference_doctype\": \"Material Request\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Supplier Addresses And Contacts\",\n \"name\": \"Address And Contacts\",\n \"reference_doctype\": \"Address\",\n \"route_options\": {\n \"party_type\": \"Supplier\"\n },\n \"type\": \"report\"\n }\n]"
}
],
"category": "Modules",
"charts": [
{
"chart_name": "Expenses",
- "label": "Expenses",
- "size": "Full"
+ "label": "Expenses"
}
],
"creation": "2020-01-28 11:50:26.195467",
@@ -51,7 +53,7 @@
"idx": 0,
"is_standard": 1,
"label": "Buying",
- "modified": "2020-03-12 16:30:40.779078",
+ "modified": "2020-04-01 11:28:51.192097",
"modified_by": "Administrator",
"module": "Buying",
"name": "Buying",
@@ -61,30 +63,30 @@
"shortcuts": [
{
"format": "{} Unpaid",
- "is_query_report": 0,
+ "label": "Purchase Invoice",
"link_to": "Purchase Invoice",
"stats_filter": "{\n \"company\": [\"like\", '%' + frappe.defaults.get_global_default(\"company\") + '%'],\n \"status\": \"Unpaid\"\n}",
"type": "DocType"
},
{
"format": "{} to receive",
- "is_query_report": 0,
+ "label": "Purchase Order",
"link_to": "Purchase Order",
"stats_filter": "{\n \"company\": [\"like\", '%' + frappe.defaults.get_global_default(\"company\") + '%'],\n \"status\": \"To Receive\"\n}",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Supplier Quotation",
"link_to": "Supplier Quotation",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Accounts Payable",
"link_to": "Accounts Payable",
"type": "Report"
},
{
- "is_query_report": 0,
+ "label": "Purchase Register",
"link_to": "Purchase Register",
"type": "Report"
}
diff --git a/erpnext/config/healthcare.py b/erpnext/config/healthcare.py
index 756d22e..2b46127 100644
--- a/erpnext/config/healthcare.py
+++ b/erpnext/config/healthcare.py
@@ -2,120 +2,27 @@
from frappe import _
def get_data():
-
return [
{
- "label": _("Consultation"),
- "icon": "icon-star",
- "items": [
- {
- "type": "doctype",
- "name": "Patient Appointment",
- "label": _("Patient Appointment"),
- },
- {
- "type": "doctype",
- "name": "Patient Encounter",
- "label": _("Patient Encounter"),
- },
- {
- "type": "doctype",
- "name": "Vital Signs",
- "label": _("Vital Signs"),
- "description": _("Record Patient Vitals"),
- },
- {
- "type": "page",
- "name": "patient_history",
- "label": _("Patient History"),
- },
- {
- "type": "page",
- "name": "appointment-analytic",
- "label": _("Appointment Analytics"),
- },
- {
- "type": "doctype",
- "name": "Clinical Procedure",
- "label": _("Clinical Procedure"),
- },
- {
- "type": "doctype",
- "name": "Inpatient Record",
- "label": _("Inpatient Record"),
- }
- ]
- },
- {
- "label": _("Laboratory"),
- "icon": "icon-list",
- "items": [
- {
- "type": "doctype",
- "name": "Lab Test",
- "label": _("Lab Test"),
- },
- {
- "type": "doctype",
- "name": "Sample Collection",
- "label": _("Sample Collection"),
- },
- {
- "type": "report",
- "name": "Lab Test Report",
- "is_query_report": True,
- "label": _("Lab Test Report"),
- }
- ]
- },
- {
"label": _("Masters"),
- "icon": "icon-list",
"items": [
{
"type": "doctype",
"name": "Patient",
"label": _("Patient"),
- "onboard": 1,
+ "onboard": 1
},
{
"type": "doctype",
"name": "Healthcare Practitioner",
"label": _("Healthcare Practitioner"),
- "onboard": 1,
+ "onboard": 1
},
{
"type": "doctype",
"name": "Practitioner Schedule",
"label": _("Practitioner Schedule"),
- },
- {
- "type": "doctype",
- "name": "Medical Code Standard",
- "label": _("Medical Code Standard"),
- },
- {
- "type": "doctype",
- "name": "Medical Code",
- "label": _("Medical Code"),
- "onboard": 1,
- },
- {
- "type": "doctype",
- "name": "Healthcare Service Unit",
- "label": _("Healthcare Service Unit")
- }
- ]
- },
- {
- "label": _("Settings"),
- "icon": "icon-cog",
- "items": [
- {
- "type": "doctype",
- "name": "Healthcare Settings",
- "label": _("Healthcare Settings"),
- "onboard": 1,
+ "onboard": 1
},
{
"type": "doctype",
@@ -124,11 +31,41 @@
},
{
"type": "doctype",
+ "name": "Healthcare Service Unit Type",
+ "label": _("Healthcare Service Unit Type")
+ },
+ {
+ "type": "doctype",
+ "name": "Healthcare Service Unit",
+ "label": _("Healthcare Service Unit")
+ },
+ {
+ "type": "doctype",
+ "name": "Medical Code Standard",
+ "label": _("Medical Code Standard")
+ },
+ {
+ "type": "doctype",
+ "name": "Medical Code",
+ "label": _("Medical Code")
+ }
+ ]
+ },
+ {
+ "label": _("Consultation Setup"),
+ "items": [
+ {
+ "type": "doctype",
"name": "Appointment Type",
"label": _("Appointment Type"),
},
{
"type": "doctype",
+ "name": "Clinical Procedure Template",
+ "label": _("Clinical Procedure Template")
+ },
+ {
+ "type": "doctype",
"name": "Prescription Dosage",
"label": _("Prescription Dosage")
},
@@ -139,6 +76,36 @@
},
{
"type": "doctype",
+ "name": "Antibiotic",
+ "label": _("Antibiotic")
+ }
+ ]
+ },
+ {
+ "label": _("Consultation"),
+ "items": [
+ {
+ "type": "doctype",
+ "name": "Patient Appointment",
+ "label": _("Patient Appointment")
+ },
+ {
+ "type": "doctype",
+ "name": "Clinical Procedure",
+ "label": _("Clinical Procedure")
+ },
+ {
+ "type": "doctype",
+ "name": "Patient Encounter",
+ "label": _("Patient Encounter")
+ },
+ {
+ "type": "doctype",
+ "name": "Vital Signs",
+ "label": _("Vital Signs")
+ },
+ {
+ "type": "doctype",
"name": "Complaint",
"label": _("Complaint")
},
@@ -149,8 +116,34 @@
},
{
"type": "doctype",
+ "name": "Fee Validity",
+ "label": _("Fee Validity")
+ }
+ ]
+ },
+ {
+ "label": _("Settings"),
+ "items": [
+ {
+ "type": "doctype",
+ "name": "Healthcare Settings",
+ "label": _("Healthcare Settings"),
+ "onboard": 1
+ }
+ ]
+ },
+ {
+ "label": _("Laboratory Setup"),
+ "items": [
+ {
+ "type": "doctype",
+ "name": "Lab Test Template",
+ "label": _("Lab Test Template")
+ },
+ {
+ "type": "doctype",
"name": "Lab Test Sample",
- "label": _("Lab Test Sample"),
+ "label": _("Lab Test Sample")
},
{
"type": "doctype",
@@ -159,28 +152,66 @@
},
{
"type": "doctype",
- "name": "Antibiotic",
- "label": _("Antibiotic")
- },
- {
- "type": "doctype",
"name": "Sensitivity",
"label": _("Sensitivity")
+ }
+ ]
+ },
+ {
+ "label": _("Laboratory"),
+ "items": [
+ {
+ "type": "doctype",
+ "name": "Lab Test",
+ "label": _("Lab Test")
},
{
"type": "doctype",
- "name": "Lab Test Template",
- "label": _("Lab Test Template")
+ "name": "Sample Collection",
+ "label": _("Sample Collection")
},
{
"type": "doctype",
- "name": "Clinical Procedure Template",
- "label": _("Clinical Procedure Template"),
+ "name": "Dosage Form",
+ "label": _("Dosage Form")
+ }
+ ]
+ },
+ {
+ "label": _("Records and History"),
+ "items": [
+ {
+ "type": "page",
+ "name": "patient_history",
+ "label": _("Patient History"),
},
{
"type": "doctype",
- "name": "Healthcare Service Unit Type",
- "label": _("Healthcare Service Unit Type")
+ "name": "Patient Medical Record",
+ "label": _("Patient Medical Record")
+ },
+ {
+ "type": "doctype",
+ "name": "Inpatient Record",
+ "label": _("Inpatient Record")
+ }
+ ]
+ },
+ {
+ "label": _("Reports"),
+ "items": [
+ {
+ "type": "report",
+ "is_query_report": True,
+ "name": "Patient Appointment Analytics",
+ "doctype": "Patient Appointment"
+ },
+ {
+ "type": "report",
+ "is_query_report": True,
+ "name": "Lab Test Report",
+ "doctype": "Lab Test",
+ "label": _("Lab Test Report")
}
]
}
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 76eb56f..d95753d 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -439,7 +439,7 @@
if account_currency not in valid_currency:
frappe.throw(_("Account {0} is invalid. Account Currency must be {1}")
- .format(account, _(" or ").join(valid_currency)))
+ .format(account, (' ' + _("or") + ' ').join(valid_currency)))
def clear_unallocated_advances(self, childtype, parentfield):
self.set(parentfield, self.get(parentfield, {"allocated_amount": ["not in", [0, None, ""]]}))
@@ -834,7 +834,7 @@
for d in self.get("payment_schedule"):
if self.doctype == "Sales Order" and getdate(d.due_date) < getdate(self.transaction_date):
- frappe.throw(_("Row {0}: Due Date cannot be before posting date").format(d.idx))
+ frappe.throw(_("Row {0}: Due Date in the Payment Terms table cannot be before Posting Date").format(d.idx))
elif d.due_date in dates:
li.append(_("{0} in row {1}").format(d.due_date, d.idx))
dates.append(d.due_date)
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index fcc9098..0e72ec2 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -45,6 +45,7 @@
self.validate_warehouse()
self.validate_from_warehouse()
self.set_supplier_address()
+ self.validate_asset_return()
if self.doctype=="Purchase Invoice":
self.validate_purchase_receipt_if_update_stock()
@@ -100,6 +101,19 @@
for d in tax_for_valuation:
d.category = 'Total'
msgprint(_('Tax Category has been changed to "Total" because all the Items are non-stock items'))
+
+ def validate_asset_return(self):
+ if self.doctype not in ['Purchase Receipt', 'Purchase Invoice'] or not self.is_return:
+ return
+
+ purchase_doc_field = 'purchase_receipt' if self.doctype == 'Purchase Receipt' else 'purchase_invoice'
+ not_cancelled_asset = [d.name for d in frappe.db.get_all("Asset", {
+ purchase_doc_field: self.return_against,
+ "docstatus": 1
+ })]
+ if self.is_return and len(not_cancelled_asset):
+ frappe.throw(_("{} has submitted assets linked to it. You need to cancel the assets to create purchase return.".format(self.return_against)),
+ title=_("Not Allowed"))
def get_asset_items(self):
if self.doctype not in ['Purchase Order', 'Purchase Invoice', 'Purchase Receipt']:
diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index 4d0520a..de76e45 100644
--- a/erpnext/controllers/status_updater.py
+++ b/erpnext/controllers/status_updater.py
@@ -69,16 +69,16 @@
["Cancelled", "eval:self.docstatus==2"],
["Closed", "eval:self.status=='Closed'"],
],
- "Purchase Invoice": [
- ["Draft", None],
- ["Submitted", "eval:self.docstatus==1"],
- ["Paid", "eval:self.outstanding_amount==0 and self.docstatus==1"],
- ["Return", "eval:self.is_return==1 and self.docstatus==1"],
- ["Debit Note Issued",
- "eval:self.outstanding_amount <= 0 and self.docstatus==1 and self.is_return==0 and get_value('Purchase Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1})"],
- ["Unpaid", "eval:self.outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()) and self.docstatus==1"],
- ["Overdue", "eval:self.outstanding_amount > 0 and getdate(self.due_date) < getdate(nowdate()) and self.docstatus==1"],
- ["Cancelled", "eval:self.docstatus==2"],
+ "Purchase Invoice": [
+ ["Draft", None],
+ ["Submitted", "eval:self.docstatus==1"],
+ ["Paid", "eval:self.outstanding_amount==0 and self.docstatus==1"],
+ ["Return", "eval:self.is_return==1 and self.docstatus==1"],
+ ["Debit Note Issued",
+ "eval:self.outstanding_amount <= 0 and self.docstatus==1 and self.is_return==0 and get_value('Purchase Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1})"],
+ ["Unpaid", "eval:self.outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()) and self.docstatus==1"],
+ ["Overdue", "eval:self.outstanding_amount > 0 and getdate(self.due_date) < getdate(nowdate()) and self.docstatus==1"],
+ ["Cancelled", "eval:self.docstatus==2"],
],
"Material Request": [
["Draft", None],
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index f6908c0..4037f2f 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -21,6 +21,7 @@
super(StockController, self).validate()
self.validate_inspection()
self.validate_serialized_batch()
+ self.validate_customer_provided_item()
def make_gl_entries(self, gl_entries=None, repost_future_gle=True, from_repost=False):
if self.docstatus == 2:
@@ -377,6 +378,15 @@
for blanket_order in blanket_orders:
frappe.get_doc("Blanket Order", blanket_order).update_ordered_qty()
+ def validate_customer_provided_item(self):
+ for d in self.get('items'):
+ # Customer Provided parts will have zero valuation rate
+ if frappe.db.get_value('Item', d.item_code, 'is_customer_provided_item'):
+ d.allow_zero_valuation_rate = 1
+ if d.parenttype in ["Delivery Note", "Sales Invoice"] and d.rate:
+ frappe.throw(_("Row #{0}: {1} cannot have {2} as it is a Customer Provided Item")
+ .format(d.idx, frappe.bold(d.item_code), frappe.bold("Rate")))
+
def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for_items=None,
warehouse_account=None, company=None):
def _delete_gl_entries(voucher_type, voucher_no):
diff --git a/erpnext/crm/desk_page/crm/crm.json b/erpnext/crm/desk_page/crm/crm.json
index 9ebbe27..4a599fe 100644
--- a/erpnext/crm/desk_page/crm/crm.json
+++ b/erpnext/crm/desk_page/crm/crm.json
@@ -1,24 +1,24 @@
{
"cards": [
{
- "icon": "fa fa-star",
- "links": "[\n {\n \"description\": \"Database of potential customers.\",\n \"label\": \"Lead\",\n \"name\": \"Lead\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Potential opportunities for selling.\",\n \"label\": \"Opportunity\",\n \"name\": \"Opportunity\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customer database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Contacts.\",\n \"label\": \"Contact\",\n \"name\": \"Contact\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Record of all communications of type email, phone, chat, visit, etc.\",\n \"label\": \"Communication\",\n \"name\": \"Communication\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Track Leads by Lead Source.\",\n \"label\": \"Lead Source\",\n \"name\": \"Lead Source\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Helps you keep tracks of Contracts based on Supplier, Customer and Employee\",\n \"label\": \"Contract\",\n \"name\": \"Contract\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Helps you manage appointments with your leads\",\n \"label\": \"Appointment\",\n \"name\": \"Appointment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Newsletter\",\n \"name\": \"Newsletter\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Sales Pipeline"
+ "hidden": 0,
+ "label": "Sales Pipeline",
+ "links": "[\n {\n \"description\": \"Database of potential customers.\",\n \"label\": \"Lead\",\n \"name\": \"Lead\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Potential opportunities for selling.\",\n \"label\": \"Opportunity\",\n \"name\": \"Opportunity\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customer database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Contacts.\",\n \"label\": \"Contact\",\n \"name\": \"Contact\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Record of all communications of type email, phone, chat, visit, etc.\",\n \"label\": \"Communication\",\n \"name\": \"Communication\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Track Leads by Lead Source.\",\n \"label\": \"Lead Source\",\n \"name\": \"Lead Source\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Helps you keep tracks of Contracts based on Supplier, Customer and Employee\",\n \"label\": \"Contract\",\n \"name\": \"Contract\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Helps you manage appointments with your leads\",\n \"label\": \"Appointment\",\n \"name\": \"Appointment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Newsletter\",\n \"name\": \"Newsletter\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-list",
- "links": "[\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Lead Details\",\n \"name\": \"Lead Details\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"icon\": \"fa fa-bar-chart\",\n \"label\": \"Sales Funnel\",\n \"name\": \"sales-funnel\",\n \"onboard\": 1,\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Prospects Engaged But Not Converted\",\n \"name\": \"Prospects Engaged But Not Converted\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Opportunity\"\n ],\n \"doctype\": \"Opportunity\",\n \"is_query_report\": true,\n \"label\": \"Minutes to First Response for Opportunity\",\n \"name\": \"Minutes to First Response for Opportunity\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Inactive Customers\",\n \"name\": \"Inactive Customers\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Campaign Efficiency\",\n \"name\": \"Campaign Efficiency\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Lead Owner Efficiency\",\n \"name\": \"Lead Owner Efficiency\",\n \"type\": \"report\"\n }\n]",
- "title": "Reports"
+ "hidden": 0,
+ "label": "Reports",
+ "links": "[\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Lead Details\",\n \"name\": \"Lead Details\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"icon\": \"fa fa-bar-chart\",\n \"label\": \"Sales Funnel\",\n \"name\": \"sales-funnel\",\n \"onboard\": 1,\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Prospects Engaged But Not Converted\",\n \"name\": \"Prospects Engaged But Not Converted\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Opportunity\"\n ],\n \"doctype\": \"Opportunity\",\n \"is_query_report\": true,\n \"label\": \"Minutes to First Response for Opportunity\",\n \"name\": \"Minutes to First Response for Opportunity\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Inactive Customers\",\n \"name\": \"Inactive Customers\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Campaign Efficiency\",\n \"name\": \"Campaign Efficiency\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Lead Owner Efficiency\",\n \"name\": \"Lead Owner Efficiency\",\n \"type\": \"report\"\n }\n]"
},
{
- "icon": "fa fa-cog",
- "links": "[\n {\n \"description\": \"Manage Customer Group Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Customer Group\",\n \"link\": \"Tree/Customer Group\",\n \"name\": \"Customer Group\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Territory Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Territory\",\n \"link\": \"Tree/Territory\",\n \"name\": \"Territory\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Sales Person Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Sales Person\",\n \"link\": \"Tree/Sales Person\",\n \"name\": \"Sales Person\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Sales campaigns.\",\n \"label\": \"Campaign\",\n \"name\": \"Campaign\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Sends Mails to lead or contact based on a Campaign schedule\",\n \"label\": \"Email Campaign\",\n \"name\": \"Email Campaign\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Send mass SMS to your contacts\",\n \"label\": \"SMS Center\",\n \"name\": \"SMS Center\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Logs for maintaining sms delivery status\",\n \"label\": \"SMS Log\",\n \"name\": \"SMS Log\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Setup SMS gateway settings\",\n \"label\": \"SMS Settings\",\n \"name\": \"SMS Settings\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Email Group\",\n \"name\": \"Email Group\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Settings"
+ "hidden": 0,
+ "label": "Settings",
+ "links": "[\n {\n \"description\": \"Manage Customer Group Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Customer Group\",\n \"link\": \"Tree/Customer Group\",\n \"name\": \"Customer Group\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Territory Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Territory\",\n \"link\": \"Tree/Territory\",\n \"name\": \"Territory\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Sales Person Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Sales Person\",\n \"link\": \"Tree/Sales Person\",\n \"name\": \"Sales Person\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Sales campaigns.\",\n \"label\": \"Campaign\",\n \"name\": \"Campaign\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Sends Mails to lead or contact based on a Campaign schedule\",\n \"label\": \"Email Campaign\",\n \"name\": \"Email Campaign\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Send mass SMS to your contacts\",\n \"label\": \"SMS Center\",\n \"name\": \"SMS Center\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Logs for maintaining sms delivery status\",\n \"label\": \"SMS Log\",\n \"name\": \"SMS Log\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Setup SMS gateway settings\",\n \"label\": \"SMS Settings\",\n \"name\": \"SMS Settings\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Email Group\",\n \"name\": \"Email Group\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-star",
- "links": "[\n {\n \"description\": \"Plan for maintenance visits.\",\n \"label\": \"Maintenance Schedule\",\n \"name\": \"Maintenance Schedule\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Visit report for maintenance call.\",\n \"label\": \"Maintenance Visit\",\n \"name\": \"Maintenance Visit\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Warranty Claim against Serial No.\",\n \"label\": \"Warranty Claim\",\n \"name\": \"Warranty Claim\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Maintenance"
+ "hidden": 0,
+ "label": "Maintenance",
+ "links": "[\n {\n \"description\": \"Plan for maintenance visits.\",\n \"label\": \"Maintenance Schedule\",\n \"name\": \"Maintenance Schedule\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Visit report for maintenance call.\",\n \"label\": \"Maintenance Visit\",\n \"name\": \"Maintenance Visit\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Warranty Claim against Serial No.\",\n \"label\": \"Warranty Claim\",\n \"name\": \"Warranty Claim\",\n \"type\": \"doctype\"\n }\n]"
}
],
"category": "Modules",
@@ -33,7 +33,7 @@
"idx": 0,
"is_standard": 1,
"label": "CRM",
- "modified": "2020-03-12 16:30:41.142037",
+ "modified": "2020-04-01 11:28:51.219999",
"modified_by": "Administrator",
"module": "CRM",
"name": "CRM",
@@ -43,25 +43,25 @@
"shortcuts": [
{
"format": "Open",
- "is_query_report": 0,
+ "label": "Lead",
"link_to": "Lead",
"stats_filter": "{\"status\":\"Open\"}",
"type": "DocType"
},
{
"format": "{} Assigned",
- "is_query_report": 0,
+ "label": "Opportunity",
"link_to": "Opportunity",
"stats_filter": "{\"_assign\": [\"like\", '%' + frappe.session.user + '%']}",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Customer",
"link_to": "Customer",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Sales Analytics",
"link_to": "Sales Analytics",
"type": "Report"
}
diff --git a/erpnext/crm/doctype/lead/lead.json b/erpnext/crm/doctype/lead/lead.json
index b3197ae..20ab51d 100644
--- a/erpnext/crm/doctype/lead/lead.json
+++ b/erpnext/crm/doctype/lead/lead.json
@@ -1,12 +1,10 @@
{
- "actions": [],
"allow_events_in_timeline": 1,
"allow_import": 1,
"autoname": "naming_series:",
"creation": "2013-04-10 11:45:37",
"doctype": "DocType",
"document_type": "Document",
- "email_append_to": 1,
"engine": "InnoDB",
"field_order": [
"organization_lead",
@@ -34,6 +32,7 @@
"notes",
"address_info",
"address_html",
+ "address_type",
"address_title",
"address_line1",
"address_line2",
@@ -285,8 +284,7 @@
"depends_on": "eval: doc.__islocal",
"fieldname": "pincode",
"fieldtype": "Data",
- "label": "Postal Code",
- "options": "Country"
+ "label": "Postal Code"
},
{
"fieldname": "column_break2",
@@ -304,7 +302,8 @@
"fieldtype": "Data",
"label": "Phone",
"oldfieldname": "contact_no",
- "oldfieldtype": "Data"
+ "oldfieldtype": "Data",
+ "options": "Phone"
},
{
"depends_on": "eval: doc.__islocal",
@@ -312,7 +311,8 @@
"fieldtype": "Data",
"label": "Mobile No.",
"oldfieldname": "mobile_no",
- "oldfieldtype": "Data"
+ "oldfieldtype": "Data",
+ "options": "Phone"
},
{
"depends_on": "eval: doc.__islocal",
@@ -433,13 +433,21 @@
"fieldname": "contact_section",
"fieldtype": "Section Break",
"label": "Contact"
+ },
+ {
+ "default": "Billing",
+ "depends_on": "eval: doc.__islocal",
+ "fieldname": "address_type",
+ "fieldtype": "Select",
+ "label": "Address Type",
+ "options": "Billing\nShipping\nOffice\nPersonal\nPlant\nPostal\nShop\nSubsidiary\nWarehouse\nCurrent\nPermanent\nOther"
}
],
"icon": "fa fa-user",
"idx": 5,
"image_field": "image",
"links": [],
- "modified": "2020-01-13 16:16:48.885228",
+ "modified": "2020-04-08 22:26:11.687110",
"modified_by": "Administrator",
"module": "CRM",
"name": "Lead",
@@ -508,9 +516,8 @@
}
],
"search_fields": "lead_name,lead_owner,status",
- "sender_field": "email_id",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "title"
-}
+}
\ No newline at end of file
diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py
index 985abfb..74b3582 100644
--- a/erpnext/crm/doctype/lead/lead.py
+++ b/erpnext/crm/doctype/lead/lead.py
@@ -126,7 +126,7 @@
self.title = self.lead_name
def create_address(self):
- address_fields = ["address_title", "address_line1", "address_line2",
+ address_fields = ["address_type", "address_title", "address_line1", "address_line2",
"city", "county", "state", "country", "pincode"]
info_fields = ["email_id", "phone", "fax"]
@@ -209,7 +209,7 @@
self.contact_doc.save()
def flush_address_and_contact_fields(self):
- fields = ['address_line1', 'address_line2', 'address_title',
+ fields = ['address_type', 'address_line1', 'address_line2', 'address_title',
'city', 'county', 'country', 'fax', 'pincode', 'state']
for field in fields:
diff --git a/erpnext/crm/doctype/opportunity/opportunity.json b/erpnext/crm/doctype/opportunity/opportunity.json
index 98a350a..6a54c5f 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.json
+++ b/erpnext/crm/doctype/opportunity/opportunity.json
@@ -423,7 +423,7 @@
"icon": "fa fa-info-sign",
"idx": 195,
"links": [],
- "modified": "2020-03-20 12:28:45.228994",
+ "modified": "2020-04-07 09:05:39.391109",
"modified_by": "Administrator",
"module": "CRM",
"name": "Opportunity",
diff --git a/erpnext/education/desk_page/education/education.json b/erpnext/education/desk_page/education/education.json
index bbd8ead..fc2697f 100644
--- a/erpnext/education/desk_page/education/education.json
+++ b/erpnext/education/desk_page/education/education.json
@@ -1,56 +1,69 @@
{
"cards": [
{
- "links": "[\n {\n \"label\": \"Student Attendance Tool\",\n \"name\": \"Student Attendance Tool\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Assessment Result Tool\",\n \"name\": \"Assessment Result Tool\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Group Creation Tool\",\n \"name\": \"Student Group Creation Tool\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Program Enrollment Tool\",\n \"name\": \"Program Enrollment Tool\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Course Scheduling Tool\",\n \"name\": \"Course Scheduling Tool\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Tools"
+ "hidden": 0,
+ "label": "Tools",
+ "links": "[\n {\n \"label\": \"Student Attendance Tool\",\n \"name\": \"Student Attendance Tool\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Assessment Result Tool\",\n \"name\": \"Assessment Result Tool\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Group Creation Tool\",\n \"name\": \"Student Group Creation Tool\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Program Enrollment Tool\",\n \"name\": \"Program Enrollment Tool\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Course Scheduling Tool\",\n \"name\": \"Course Scheduling Tool\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"dependencies\": [\n \"Program Enrollment\"\n ],\n \"doctype\": \"Program Enrollment\",\n \"is_query_report\": true,\n \"label\": \"Student and Guardian Contact Details\",\n \"name\": \"Student and Guardian Contact Details\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Student Attendance\"\n ],\n \"doctype\": \"Student Attendance\",\n \"is_query_report\": true,\n \"label\": \"Student Monthly Attendance Sheet\",\n \"name\": \"Student Monthly Attendance Sheet\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Fees\"\n ],\n \"doctype\": \"Fees\",\n \"is_query_report\": true,\n \"label\": \"Student Fee Collection\",\n \"name\": \"Student Fee Collection\",\n \"type\": \"report\"\n }\n]",
- "title": "Other Reports"
+ "hidden": 0,
+ "label": "Other Reports",
+ "links": "[\n {\n \"dependencies\": [\n \"Program Enrollment\"\n ],\n \"doctype\": \"Program Enrollment\",\n \"is_query_report\": true,\n \"label\": \"Student and Guardian Contact Details\",\n \"name\": \"Student and Guardian Contact Details\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Student Attendance\"\n ],\n \"doctype\": \"Student Attendance\",\n \"is_query_report\": true,\n \"label\": \"Student Monthly Attendance Sheet\",\n \"name\": \"Student Monthly Attendance Sheet\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Fees\"\n ],\n \"doctype\": \"Fees\",\n \"is_query_report\": true,\n \"label\": \"Student Fee Collection\",\n \"name\": \"Student Fee Collection\",\n \"type\": \"report\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Student Category\",\n \"name\": \"Student Category\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Batch Name\",\n \"name\": \"Student Batch Name\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Grading Scale\",\n \"name\": \"Grading Scale\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Academic Term\",\n \"name\": \"Academic Term\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Academic Year\",\n \"name\": \"Academic Year\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Education Settings\",\n \"name\": \"Education Settings\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Settings"
+ "hidden": 0,
+ "label": "Settings",
+ "links": "[\n {\n \"label\": \"Student Category\",\n \"name\": \"Student Category\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Batch Name\",\n \"name\": \"Student Batch Name\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Grading Scale\",\n \"name\": \"Grading Scale\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Academic Term\",\n \"name\": \"Academic Term\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Academic Year\",\n \"name\": \"Academic Year\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Education Settings\",\n \"name\": \"Education Settings\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Article\",\n \"name\": \"Article\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Video\",\n \"name\": \"Video\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Quiz\",\n \"name\": \"Quiz\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Content Masters"
+ "hidden": 0,
+ "label": "Content Masters",
+ "links": "[\n {\n \"label\": \"Article\",\n \"name\": \"Article\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Video\",\n \"name\": \"Video\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Quiz\",\n \"name\": \"Quiz\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Student Attendance\",\n \"name\": \"Student Attendance\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Leave Application\",\n \"name\": \"Student Leave Application\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Student Attendance\"\n ],\n \"doctype\": \"Student Attendance\",\n \"is_query_report\": true,\n \"label\": \"Absent Student Report\",\n \"name\": \"Absent Student Report\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Student Attendance\"\n ],\n \"doctype\": \"Student Attendance\",\n \"is_query_report\": true,\n \"label\": \"Student Batch-Wise Attendance\",\n \"name\": \"Student Batch-Wise Attendance\",\n \"type\": \"report\"\n }\n]",
- "title": "Attendance"
+ "hidden": 0,
+ "label": "Attendance",
+ "links": "[\n {\n \"label\": \"Student Attendance\",\n \"name\": \"Student Attendance\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Leave Application\",\n \"name\": \"Student Leave Application\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Student Attendance\"\n ],\n \"doctype\": \"Student Attendance\",\n \"is_query_report\": true,\n \"label\": \"Absent Student Report\",\n \"name\": \"Absent Student Report\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Student Attendance\"\n ],\n \"doctype\": \"Student Attendance\",\n \"is_query_report\": true,\n \"label\": \"Student Batch-Wise Attendance\",\n \"name\": \"Student Batch-Wise Attendance\",\n \"type\": \"report\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Student Applicant\",\n \"name\": \"Student Applicant\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Admission\",\n \"name\": \"Student Admission\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Program Enrollment\",\n \"name\": \"Program Enrollment\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Admission"
+ "hidden": 0,
+ "label": "Admission",
+ "links": "[\n {\n \"label\": \"Student Applicant\",\n \"name\": \"Student Applicant\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Admission\",\n \"name\": \"Student Admission\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Program Enrollment\",\n \"name\": \"Program Enrollment\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Assessment Plan\",\n \"name\": \"Assessment Plan\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Assessment Group\",\n \"link\": \"Tree/Assessment Group\",\n \"name\": \"Assessment Group\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Assessment Result\",\n \"name\": \"Assessment Result\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Assessment Criteria\",\n \"name\": \"Assessment Criteria\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Assessment"
+ "hidden": 0,
+ "label": "Assessment",
+ "links": "[\n {\n \"label\": \"Assessment Plan\",\n \"name\": \"Assessment Plan\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Assessment Group\",\n \"link\": \"Tree/Assessment Group\",\n \"name\": \"Assessment Group\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Assessment Result\",\n \"name\": \"Assessment Result\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Assessment Criteria\",\n \"name\": \"Assessment Criteria\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Student\",\n \"name\": \"Student\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Guardian\",\n \"name\": \"Guardian\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Log\",\n \"name\": \"Student Log\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Group\",\n \"name\": \"Student Group\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Student"
+ "hidden": 0,
+ "label": "Student",
+ "links": "[\n {\n \"label\": \"Student\",\n \"name\": \"Student\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Guardian\",\n \"name\": \"Guardian\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Log\",\n \"name\": \"Student Log\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Student Group\",\n \"name\": \"Student Group\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Program\",\n \"name\": \"Program\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Course\",\n \"name\": \"Course\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Topic\",\n \"name\": \"Topic\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Instructor\",\n \"name\": \"Instructor\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Room\",\n \"name\": \"Room\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]",
- "title": "Masters"
+ "hidden": 0,
+ "label": "Masters",
+ "links": "[\n {\n \"label\": \"Program\",\n \"name\": \"Program\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Course\",\n \"name\": \"Course\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Topic\",\n \"name\": \"Topic\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Instructor\",\n \"name\": \"Instructor\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Room\",\n \"name\": \"Room\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Course Enrollment\",\n \"name\": \"Course Enrollment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Course Activity\",\n \"name\": \"Course Activity\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Quiz Activity\",\n \"name\": \"Quiz Activity\",\n \"type\": \"doctype\"\n }\n]",
- "title": "LMS Activity"
+ "hidden": 0,
+ "label": "LMS Activity",
+ "links": "[\n {\n \"label\": \"Course Enrollment\",\n \"name\": \"Course Enrollment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Course Activity\",\n \"name\": \"Course Activity\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Quiz Activity\",\n \"name\": \"Quiz Activity\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Course Schedule\",\n \"name\": \"Course Schedule\",\n \"route\": \"#List/Course Schedule/Calendar\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Course Scheduling Tool\",\n \"name\": \"Course Scheduling Tool\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Schedule"
+ "hidden": 0,
+ "label": "Schedule",
+ "links": "[\n {\n \"label\": \"Course Schedule\",\n \"name\": \"Course Schedule\",\n \"route\": \"#List/Course Schedule/Calendar\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Course Scheduling Tool\",\n \"name\": \"Course Scheduling Tool\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Fees\",\n \"name\": \"Fees\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Fee Schedule\",\n \"name\": \"Fee Schedule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Fee Structure\",\n \"name\": \"Fee Structure\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Fee Category\",\n \"name\": \"Fee Category\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Fees"
+ "hidden": 0,
+ "label": "Fees",
+ "links": "[\n {\n \"label\": \"Fees\",\n \"name\": \"Fees\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Fee Schedule\",\n \"name\": \"Fee Schedule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Fee Structure\",\n \"name\": \"Fee Structure\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Fee Category\",\n \"name\": \"Fee Category\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"dependencies\": [\n \"Assessment Result\"\n ],\n \"doctype\": \"Assessment Result\",\n \"is_query_report\": true,\n \"label\": \"Course wise Assessment Report\",\n \"name\": \"Course wise Assessment Report\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Assessment Result\"\n ],\n \"doctype\": \"Assessment Result\",\n \"is_query_report\": true,\n \"label\": \"Final Assessment Grades\",\n \"name\": \"Final Assessment Grades\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Assessment Plan\"\n ],\n \"doctype\": \"Assessment Plan\",\n \"is_query_report\": true,\n \"label\": \"Assessment Plan Status\",\n \"name\": \"Assessment Plan Status\",\n \"type\": \"report\"\n },\n {\n \"label\": \"Student Report Generation Tool\",\n \"name\": \"Student Report Generation Tool\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Assessment Reports"
+ "hidden": 0,
+ "label": "Assessment Reports",
+ "links": "[\n {\n \"dependencies\": [\n \"Assessment Result\"\n ],\n \"doctype\": \"Assessment Result\",\n \"is_query_report\": true,\n \"label\": \"Course wise Assessment Report\",\n \"name\": \"Course wise Assessment Report\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Assessment Result\"\n ],\n \"doctype\": \"Assessment Result\",\n \"is_query_report\": true,\n \"label\": \"Final Assessment Grades\",\n \"name\": \"Final Assessment Grades\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Assessment Plan\"\n ],\n \"doctype\": \"Assessment Plan\",\n \"is_query_report\": true,\n \"label\": \"Assessment Plan Status\",\n \"name\": \"Assessment Plan Status\",\n \"type\": \"report\"\n },\n {\n \"label\": \"Student Report Generation Tool\",\n \"name\": \"Student Report Generation Tool\",\n \"type\": \"doctype\"\n }\n]"
}
],
"category": "Domains",
@@ -64,7 +77,7 @@
"idx": 0,
"is_standard": 1,
"label": "Education",
- "modified": "2020-03-12 16:30:37.217514",
+ "modified": "2020-04-01 11:28:51.011309",
"modified_by": "Administrator",
"module": "Education",
"name": "Education",
diff --git a/erpnext/education/report/student_and_guardian_contact_details/student_and_guardian_contact_details.py b/erpnext/education/report/student_and_guardian_contact_details/student_and_guardian_contact_details.py
index c2ac0d7..5bebd43 100644
--- a/erpnext/education/report/student_and_guardian_contact_details/student_and_guardian_contact_details.py
+++ b/erpnext/education/report/student_and_guardian_contact_details/student_and_guardian_contact_details.py
@@ -14,7 +14,7 @@
student_batch_name = filters.get("student_batch_name")
columns = get_columns()
-
+
program_enrollments = frappe.get_list("Program Enrollment", fields=["student", "student_name"],
filters={"academic_year": academic_year, "program": program, "student_batch_name": student_batch_name})
@@ -46,9 +46,9 @@
def get_columns():
columns = [
- _(" Group Roll No") + "::60",
- _("Student ID") + ":Link/Student:90",
- _("Student Name") + "::150",
+ _("Group Roll No") + "::60",
+ _("Student ID") + ":Link/Student:90",
+ _("Student Name") + "::150",
_("Student Mobile No.") + "::110",
_("Student Email ID") + "::125",
_("Student Address") + "::175",
@@ -84,10 +84,10 @@
guardian_list = list(set([g.guardian for g in guardian_details])) or ['']
- guardian_mobile_no = dict(frappe.db.sql("""select name, mobile_number from `tabGuardian`
+ guardian_mobile_no = dict(frappe.db.sql("""select name, mobile_number from `tabGuardian`
where name in (%s)""" % ", ".join(['%s']*len(guardian_list)), tuple(guardian_list)))
- guardian_email_id = dict(frappe.db.sql("""select name, email_address from `tabGuardian`
+ guardian_email_id = dict(frappe.db.sql("""select name, email_address from `tabGuardian`
where name in (%s)""" % ", ".join(['%s']*len(guardian_list)), tuple(guardian_list)))
for guardian in guardian_details:
diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
index 3bc8db5..cc75a0a 100644
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
@@ -121,7 +121,7 @@
time.sleep(delay)
continue
- mws_settings.enable_synch = 0
+ mws_settings.enable_sync = 0
mws_settings.save()
frappe.throw(_("Sync has been temporarily disabled because maximum retries have been exceeded"))
diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_api.py b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_api.py
index 9925dc4..f713684 100755
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_api.py
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_api.py
@@ -39,16 +39,19 @@
# for a list of the end points and marketplace IDs
MARKETPLACES = {
- "CA" : "https://mws.amazonservices.ca", #A2EUQ1WTGCTBG2
- "US" : "https://mws.amazonservices.com", #ATVPDKIKX0DER",
- "DE" : "https://mws-eu.amazonservices.com", #A1PA6795UKMFR9
- "ES" : "https://mws-eu.amazonservices.com", #A1RKKUPIHCS9HS
- "FR" : "https://mws-eu.amazonservices.com", #A13V1IB3VIYZZH
- "IN" : "https://mws.amazonservices.in", #A21TJRUUN4KGV
- "IT" : "https://mws-eu.amazonservices.com", #APJ6JRA9NG5V4
- "UK" : "https://mws-eu.amazonservices.com", #A1F83G8C2ARO7P
- "JP" : "https://mws.amazonservices.jp", #A1VC38T7YXB528
- "CN" : "https://mws.amazonservices.com.cn", #AAHKV2X7AFYLW
+ "CA": "https://mws.amazonservices.ca", #A2EUQ1WTGCTBG2
+ "US": "https://mws.amazonservices.com", #ATVPDKIKX0DER",
+ "DE": "https://mws-eu.amazonservices.com", #A1PA6795UKMFR9
+ "ES": "https://mws-eu.amazonservices.com", #A1RKKUPIHCS9HS
+ "FR": "https://mws-eu.amazonservices.com", #A13V1IB3VIYZZH
+ "IN": "https://mws.amazonservices.in", #A21TJRUUN4KGV
+ "IT": "https://mws-eu.amazonservices.com", #APJ6JRA9NG5V4
+ "UK": "https://mws-eu.amazonservices.com", #A1F83G8C2ARO7P
+ "JP": "https://mws.amazonservices.jp", #A1VC38T7YXB528
+ "CN": "https://mws.amazonservices.com.cn", #AAHKV2X7AFYLW
+ "AE": " https://mws.amazonservices.ae", #A2VIGQ35RCS4UG
+ "MX": "https://mws.amazonservices.com.mx", #A1AM78C64UM0Y8
+ "BR": "https://mws.amazonservices.com", #A2Q3Y263D00KWC
}
diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.json b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.json
index 607ca4f..5a678e7 100644
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.json
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.json
@@ -1,974 +1,237 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "autoname": "",
- "beta": 0,
- "creation": "2018-07-31 05:51:41.357047",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "actions": [],
+ "creation": "2018-07-31 05:51:41.357047",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "enable_amazon",
+ "mws_credentials",
+ "seller_id",
+ "aws_access_key_id",
+ "mws_auth_token",
+ "secret_key",
+ "column_break_4",
+ "market_place_id",
+ "region",
+ "domain",
+ "section_break_13",
+ "company",
+ "warehouse",
+ "item_group",
+ "price_list",
+ "column_break_17",
+ "customer_group",
+ "territory",
+ "customer_type",
+ "market_place_account_group",
+ "section_break_12",
+ "after_date",
+ "taxes_charges",
+ "sync_products",
+ "sync_orders",
+ "column_break_10",
+ "enable_sync",
+ "max_retry_limit"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "enable_amazon",
- "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": "Enable Amazon",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "enable_amazon",
+ "fieldtype": "Check",
+ "label": "Enable Amazon"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "collapsible_depends_on": "",
- "columns": 0,
- "fieldname": "mws_credentials",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "MWS Credentials",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "mws_credentials",
+ "fieldtype": "Section Break",
+ "label": "MWS Credentials"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "seller_id",
- "fieldtype": "Data",
- "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": "Seller ID",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "seller_id",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Seller ID",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "aws_access_key_id",
- "fieldtype": "Data",
- "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": "AWS Access Key ID",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "aws_access_key_id",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "AWS Access Key ID",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "mws_auth_token",
- "fieldtype": "Data",
- "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": "MWS Auth Token",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "mws_auth_token",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "MWS Auth Token",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "secret_key",
- "fieldtype": "Data",
- "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": "Secret Key",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "secret_key",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Secret Key",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 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,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_4",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "market_place_id",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Market Place ID",
- "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,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "market_place_id",
+ "fieldtype": "Data",
+ "label": "Market Place ID",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "region",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Region",
- "length": 0,
- "no_copy": 0,
- "options": "\nIN\nCN\nJP\nBR\nAU\nES\nUK\nFR\nDE\nIT\nCA\nUS\nMX",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "region",
+ "fieldtype": "Select",
+ "label": "Region",
+ "options": "\nAE\nAU\nBR\nCA\nCN\nDE\nES\nFR\nIN\nJP\nIT\nMX\nUK\nUS",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "domain",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Domain",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "domain",
+ "fieldtype": "Data",
+ "label": "Domain",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "section_break_13",
- "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,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "section_break_13",
+ "fieldtype": "Section Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "company",
- "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": "Company",
- "length": 0,
- "no_copy": 0,
- "options": "Company",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "label": "Company",
+ "options": "Company",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "warehouse",
- "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": "Warehouse",
- "length": 0,
- "no_copy": 0,
- "options": "Warehouse",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "warehouse",
+ "fieldtype": "Link",
+ "label": "Warehouse",
+ "options": "Warehouse",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "item_group",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Item Group",
- "length": 0,
- "no_copy": 0,
- "options": "Item Group",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "item_group",
+ "fieldtype": "Link",
+ "label": "Item Group",
+ "options": "Item Group",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "price_list",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Price List",
- "length": 0,
- "no_copy": 0,
- "options": "Price List",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "price_list",
+ "fieldtype": "Link",
+ "label": "Price List",
+ "options": "Price List",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_17",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_17",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "customer_group",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Customer Group",
- "length": 0,
- "no_copy": 0,
- "options": "Customer Group",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "customer_group",
+ "fieldtype": "Link",
+ "label": "Customer Group",
+ "options": "Customer Group",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "territory",
- "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": "Territory",
- "length": 0,
- "no_copy": 0,
- "options": "Territory",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "territory",
+ "fieldtype": "Link",
+ "label": "Territory",
+ "options": "Territory",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "customer_type",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Customer Type",
- "length": 0,
- "no_copy": 0,
- "options": "Individual\nCompany",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "customer_type",
+ "fieldtype": "Select",
+ "label": "Customer Type",
+ "options": "Individual\nCompany",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "market_place_account_group",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Market Place Account Group",
- "length": 0,
- "no_copy": 0,
- "options": "Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "market_place_account_group",
+ "fieldtype": "Link",
+ "label": "Market Place Account Group",
+ "options": "Account",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "section_break_12",
- "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,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "section_break_12",
+ "fieldtype": "Section Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "Amazon will synch data updated after this date",
- "fieldname": "after_date",
- "fieldtype": "Datetime",
- "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": "After Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "description": "Amazon will synch data updated after this date",
+ "fieldname": "after_date",
+ "fieldtype": "Datetime",
+ "label": "After Date",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "Get financial breakup of Taxes and charges data by Amazon ",
- "fieldname": "taxes_charges",
- "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": "Synch Taxes and Charges",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "description": "Get financial breakup of Taxes and charges data by Amazon ",
+ "fieldname": "taxes_charges",
+ "fieldtype": "Check",
+ "label": "Sync Taxes and Charges"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "Always synch your products from Amazon MWS before synching the Orders details",
- "fieldname": "synch_products",
- "fieldtype": "Button",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Synch Products",
- "length": 0,
- "no_copy": 0,
- "options": "get_products_details",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_10",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "Click this button to pull your Sales Order data from Amazon MWS.",
- "fieldname": "synch_orders",
- "fieldtype": "Button",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Synch Orders",
- "length": 0,
- "no_copy": 0,
- "options": "get_order_details",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "3",
+ "fieldname": "max_retry_limit",
+ "fieldtype": "Int",
+ "label": "Max Retry Limit"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_10",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "description": "Always sync your products from Amazon MWS before synching the Orders details",
+ "fieldname": "sync_products",
+ "fieldtype": "Button",
+ "label": "Sync Products",
+ "options": "get_products_details"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "description": "Check this to enable a scheduled Daily synchronization routine via scheduler",
- "fieldname": "enable_synch",
- "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": "Enable Scheduled Synch",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "description": "Click this button to pull your Sales Order data from Amazon MWS.",
+ "fieldname": "sync_orders",
+ "fieldtype": "Button",
+ "label": "Sync Orders",
+ "options": "get_order_details"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "3",
- "fieldname": "max_retry_limit",
- "fieldtype": "Int",
- "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 Retry Limit",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "default": "0",
+ "description": "Check this to enable a scheduled Daily synchronization routine via scheduler",
+ "fieldname": "enable_sync",
+ "fieldtype": "Check",
+ "label": "Enable Scheduled Sync"
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 1,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-09-07 16:45:44.439834",
- "modified_by": "Administrator",
- "module": "ERPNext Integrations",
- "name": "Amazon MWS Settings",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "issingle": 1,
+ "links": [],
+ "modified": "2020-04-07 14:26:20.174848",
+ "modified_by": "Administrator",
+ "module": "ERPNext Integrations",
+ "name": "Amazon MWS Settings",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 0,
- "role": "System Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "print": 1,
+ "read": 1,
+ "role": "System Manager",
+ "share": 1,
"write": 1
}
- ],
- "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1,
- "track_seen": 0,
- "track_views": 0
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
}
\ No newline at end of file
diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.py b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.py
index c222afb..899b7ff 100644
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.py
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.py
@@ -7,14 +7,15 @@
from frappe.model.document import Document
import dateutil
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
+from erpnext.erpnext_integrations.doctype.amazon_mws_settings.amazon_methods import get_orders
class AmazonMWSSettings(Document):
def validate(self):
if self.enable_amazon == 1:
- self.enable_synch = 1
+ self.enable_sync = 1
setup_custom_fields()
else:
- self.enable_synch = 0
+ self.enable_sync = 0
def get_products_details(self):
if self.enable_amazon == 1:
@@ -27,7 +28,7 @@
def schedule_get_order_details():
mws_settings = frappe.get_doc("Amazon MWS Settings")
- if mws_settings.enable_synch and mws_settings.enable_amazon:
+ if mws_settings.enable_sync and mws_settings.enable_amazon:
after_date = dateutil.parser.parse(mws_settings.after_date).strftime("%Y-%m-%d")
get_orders(after_date = after_date)
diff --git a/erpnext/healthcare/desk_page/healthcare/healthcare.json b/erpnext/healthcare/desk_page/healthcare/healthcare.json
index 258a72c..54798ba 100644
--- a/erpnext/healthcare/desk_page/healthcare/healthcare.json
+++ b/erpnext/healthcare/desk_page/healthcare/healthcare.json
@@ -1,28 +1,49 @@
{
"cards": [
{
- "icon": "icon-cog",
- "links": "[\n {\n \"label\": \"Healthcare Settings\",\n \"name\": \"Healthcare Settings\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Medical Department\",\n \"name\": \"Medical Department\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Appointment Type\",\n \"name\": \"Appointment Type\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Prescription Dosage\",\n \"name\": \"Prescription Dosage\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Prescription Duration\",\n \"name\": \"Prescription Duration\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Complaint\",\n \"name\": \"Complaint\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Diagnosis\",\n \"name\": \"Diagnosis\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Lab Test Sample\",\n \"name\": \"Lab Test Sample\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Lab Test UOM\",\n \"name\": \"Lab Test UOM\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Antibiotic\",\n \"name\": \"Antibiotic\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Sensitivity\",\n \"name\": \"Sensitivity\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Lab Test Template\",\n \"name\": \"Lab Test Template\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Clinical Procedure Template\",\n \"name\": \"Clinical Procedure Template\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Healthcare Service Unit Type\",\n \"name\": \"Healthcare Service Unit Type\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Settings"
- },
- {
- "icon": "icon-list",
- "links": "[\n {\n \"label\": \"Lab Test\",\n \"name\": \"Lab Test\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Sample Collection\",\n \"name\": \"Sample Collection\",\n \"type\": \"doctype\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Lab Test Report\",\n \"name\": \"Lab Test Report\",\n \"type\": \"report\"\n }\n]",
- "title": "Laboratory"
- },
- {
- "icon": "icon-list",
- "links": "[\n {\n \"label\": \"Patient\",\n \"name\": \"Patient\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Healthcare Practitioner\",\n \"name\": \"Healthcare Practitioner\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Practitioner Schedule\",\n \"name\": \"Practitioner Schedule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Medical Code Standard\",\n \"name\": \"Medical Code Standard\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Medical Code\",\n \"name\": \"Medical Code\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Healthcare Service Unit\",\n \"name\": \"Healthcare Service Unit\",\n \"type\": \"doctype\"\n }\n]",
+ "icon": "",
+ "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient\",\n\t\t\"label\": \"Patient\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Practitioner\",\n\t\t\"label\":\"Healthcare Practitioner\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Practitioner Schedule\",\n\t\t\"label\": \"Practitioner Schedule\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Department\",\n\t\t\"label\": \"Medical Department\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Service Unit Type\",\n\t\t\"label\": \"Healthcare Service Unit Type\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Service Unit\",\n\t\t\"label\": \"Healthcare Service Unit\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Code Standard\",\n\t\t\"label\": \"Medical Code Standard\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Code\",\n\t\t\"label\": \"Medical Code\"\n\t}\n]",
"title": "Masters"
},
{
+ "icon": "",
+ "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Appointment Type\",\n\t\t\"label\": \"Appointment Type\"\n },\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Clinical Procedure Template\",\n\t\t\"label\": \"Clinical Procedure Template\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Prescription Dosage\",\n\t\t\"label\": \"Prescription Dosage\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Prescription Duration\",\n\t\t\"label\": \"Prescription Duration\"\n\t},\n\t{\n\t \"type\": \"doctype\",\n\t\t\"name\": \"Antibiotic\",\n\t\t\"label\": \"Antibiotic\"\n\t}\n]",
+ "title": "Consultation Setup"
+ },
+ {
"icon": "icon-star",
- "links": "[\n {\n \"label\": \"Patient Appointment\",\n \"name\": \"Patient Appointment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Patient Encounter\",\n \"name\": \"Patient Encounter\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Record Patient Vitals\",\n \"label\": \"Vital Signs\",\n \"name\": \"Vital Signs\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Patient History\",\n \"name\": \"patient_history\",\n \"type\": \"page\"\n },\n {\n \"label\": \"Appointment Analytics\",\n \"name\": \"appointment-analytic\",\n \"type\": \"page\"\n },\n {\n \"label\": \"Clinical Procedure\",\n \"name\": \"Clinical Procedure\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Inpatient Record\",\n \"name\": \"Inpatient Record\",\n \"type\": \"doctype\"\n }\n]",
+ "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Appointment\",\n\t\t\"label\": \"Patient Appointment\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Clinical Procedure\",\n\t\t\"label\": \"Clinical Procedure\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Encounter\",\n\t\t\"label\": \"Patient Encounter\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Vital Signs\",\n\t\t\"label\": \"Vital Signs\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Complaint\",\n\t\t\"label\": \"Complaint\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Diagnosis\",\n\t\t\"label\": \"Diagnosis\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Fee Validity\",\n\t\t\"label\": \"Fee Validity\"\n\t}\n]",
"title": "Consultation"
+ },
+ {
+ "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Settings\",\n\t\t\"label\": \"Healthcare Settings\",\n\t\t\"onboard\": 1\n\t}\n]",
+ "title": "Settings"
+ },
+ {
+ "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test Template\",\n\t\t\"label\": \"Lab Test Template\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test Sample\",\n\t\t\"label\": \"Lab Test Sample\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test UOM\",\n\t\t\"label\": \"Lab Test UOM\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Sensitivity\",\n\t\t\"label\": \"Sensitivity\"\n\t}\n]",
+ "title": "Laboratory Setup"
+ },
+ {
+ "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test\",\n\t\t\"label\": \"Lab Test\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Sample Collection\",\n\t\t\"label\": \"Sample Collection\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Dosage Form\",\n\t\t\"label\": \"Dosage Form\"\n\t}\n]",
+ "title": "Laboratory"
+ },
+ {
+ "links": "[\n\t{\n\t\t\"type\": \"page\",\n\t\t\"name\": \"patient_history\",\n\t\t\"label\": \"Patient History\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Medical Record\",\n\t\t\"label\": \"Patient Medical Record\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Inpatient Record\",\n\t\t\"label\": \"Inpatient Record\"\n\t}\n]",
+ "title": "Records and History"
+ },
+ {
+ "links": "[\n\t{\n\t\t\"type\": \"report\",\n\t\t\"is_query_report\": true,\n\t\t\"name\": \"Patient Appointment Analytics\",\n\t\t\"doctype\": \"Patient Appointment\"\n\t},\n\t{\n\t\t\"type\": \"report\",\n\t\t\"is_query_report\": true,\n\t\t\"name\": \"Lab Test Report\",\n\t\t\"doctype\": \"Lab Test\",\n\t\t\"label\": \"Lab Test Report\"\n\t}\n]",
+ "title": "Reports"
}
],
"category": "Domains",
- "charts": [],
+ "charts": [
+ {
+ "chart_name": "Patient Appointments",
+ "label": "Patient Appointments"
+ }
+ ],
+ "charts_label": "",
"creation": "2020-03-02 17:23:17.919682",
"developer_mode_only": 0,
"disable_user_customization": 0,
@@ -32,7 +53,7 @@
"idx": 0,
"is_standard": 1,
"label": "Healthcare",
- "modified": "2020-03-12 16:30:36.952979",
+ "modified": "2020-03-26 16:10:44.629795",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Healthcare",
@@ -40,5 +61,37 @@
"pin_to_bottom": 0,
"pin_to_top": 0,
"restrict_to_domain": "Healthcare",
- "shortcuts": []
+ "shortcuts": [
+ {
+ "format": "{} Open",
+ "is_query_report": 0,
+ "link_to": "Patient Appointment",
+ "stats_filter": "{\n \"status\": \"Open\"\n}",
+ "type": "DocType"
+ },
+ {
+ "format": "{} Active",
+ "is_query_report": 0,
+ "link_to": "Patient",
+ "stats_filter": "{\n \"status\": \"Active\"\n}",
+ "type": "DocType"
+ },
+ {
+ "format": "{} Vacant",
+ "is_query_report": 0,
+ "link_to": "Healthcare Service Unit",
+ "stats_filter": "{\n \"occupancy_status\": \"Vacant\",\n \"is_group\": 0\n}",
+ "type": "DocType"
+ },
+ {
+ "is_query_report": 0,
+ "link_to": "Healthcare Practitioner",
+ "type": "DocType"
+ },
+ {
+ "is_query_report": 0,
+ "link_to": "patient_history",
+ "type": "Page"
+ }
+ ]
}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/appointment_type/appointment_type.json b/erpnext/healthcare/doctype/appointment_type/appointment_type.json
index ceabce2..58753bb 100644
--- a/erpnext/healthcare/doctype/appointment_type/appointment_type.json
+++ b/erpnext/healthcare/doctype/appointment_type/appointment_type.json
@@ -1,213 +1,94 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 1,
- "allow_rename": 1,
- "autoname": "field:appointment_type",
- "beta": 1,
- "creation": "2016-07-22 11:52:34.953019",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 0,
+ "actions": [],
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "field:appointment_type",
+ "beta": 1,
+ "creation": "2016-07-22 11:52:34.953019",
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "engine": "InnoDB",
+ "field_order": [
+ "appointment_type",
+ "ip",
+ "default_duration",
+ "color"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 1,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "appointment_type",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Type",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 1,
+ "allow_in_quick_entry": 1,
+ "fieldname": "appointment_type",
+ "fieldtype": "Data",
+ "ignore_xss_filter": 1,
+ "in_list_view": 1,
+ "label": "Type",
+ "reqd": 1,
+ "translatable": 1,
"unique": 1
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 1,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "ip",
- "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": "Is Inpatient",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "bold": 1,
+ "default": "0",
+ "fieldname": "ip",
+ "fieldtype": "Check",
+ "label": "Is Inpatient",
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 1,
- "allow_on_submit": 0,
- "bold": 1,
- "collapsible": 0,
- "columns": 0,
- "description": "In Minutes",
- "fieldname": "default_duration",
- "fieldtype": "Int",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Default Duration",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "allow_in_quick_entry": 1,
+ "bold": 1,
+ "fieldname": "default_duration",
+ "fieldtype": "Int",
+ "in_filter": 1,
+ "in_list_view": 1,
+ "label": "Default Duration (In Minutes)"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 1,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "color",
- "fieldtype": "Color",
- "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": "Color",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "allow_in_quick_entry": 1,
+ "fieldname": "color",
+ "fieldtype": "Color",
+ "in_list_view": 1,
+ "label": "Color",
+ "no_copy": 1,
+ "report_hide": 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": 0,
- "max_attachments": 0,
- "modified": "2018-08-08 12:57:54.544216",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Appointment Type",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "links": [],
+ "modified": "2020-02-03 21:06:05.833050",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Appointment Type",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Healthcare Administrator",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Healthcare Administrator",
+ "share": 1,
"write": 1
- },
+ },
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Physician",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Physician",
+ "share": 1,
"write": 1
}
- ],
- "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "search_fields": "appointment_type",
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "",
- "track_changes": 0,
- "track_seen": 0,
- "track_views": 0
+ ],
+ "quick_entry": 1,
+ "restrict_to_domain": "Healthcare",
+ "search_fields": "appointment_type",
+ "sort_field": "modified",
+ "sort_order": "DESC"
}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/appointment_type/appointment_type_dashboard.py b/erpnext/healthcare/doctype/appointment_type/appointment_type_dashboard.py
new file mode 100644
index 0000000..845e446
--- /dev/null
+++ b/erpnext/healthcare/doctype/appointment_type/appointment_type_dashboard.py
@@ -0,0 +1,13 @@
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+ return {
+ 'fieldname': 'appointment_type',
+ 'transactions': [
+ {
+ 'label': _('Patient Appointments'),
+ 'items': ['Patient Appointment']
+ },
+ ]
+ }
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
index fa91884..5f36bdd 100644
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
@@ -4,244 +4,285 @@
frappe.ui.form.on('Clinical Procedure', {
setup: function(frm) {
frm.set_query('batch_no', 'items', function(doc, cdt, cdn) {
- var item = locals[cdt][cdn];
- if(!item.item_code) {
- frappe.throw(__("Please enter Item Code to get Batch Number"));
+ let item = locals[cdt][cdn];
+ if (!item.item_code) {
+ frappe.throw(__('Please enter Item Code to get Batch Number'));
} else {
+ let filters = {'item_code': item.item_code};
+
if (frm.doc.status == 'In Progress') {
- var filters = {
- 'item_code': item.item_code,
- 'posting_date': frm.doc.start_date || frappe.datetime.nowdate()
- };
- if(frm.doc.warehouse) filters["warehouse"] = frm.doc.warehouse;
- } else {
- filters = {
- 'item_code': item.item_code
- };
+ filters['posting_date'] = frm.doc.start_date || frappe.datetime.nowdate();
+ if (frm.doc.warehouse) filters['warehouse'] = frm.doc.warehouse;
}
+
return {
- query : "erpnext.controllers.queries.get_batch_no",
+ query : 'erpnext.controllers.queries.get_batch_no',
filters: filters
};
}
});
},
+
refresh: function(frm) {
- frm.set_query("patient", function () {
+ frm.set_query('patient', function () {
return {
- filters: {"disabled": 0}
+ filters: {'status': ['!=', 'Disabled']}
};
});
- frm.set_query("appointment", function () {
+
+ frm.set_query('appointment', function () {
return {
filters: {
- "procedure_template": ["not in", null],
- "status": ['in', 'Open, Scheduled']
+ 'procedure_template': ['not in', null],
+ 'status': ['in', 'Open, Scheduled']
}
};
});
- frm.set_query("service_unit", function(){
+
+ frm.set_query('service_unit', function() {
return {
filters: {
- "is_group": false,
- "allow_appointments": true
+ 'is_group': false,
+ 'allow_appointments': true
}
};
});
- frm.set_query("practitioner", function() {
+
+ frm.set_query('practitioner', function() {
return {
filters: {
'department': frm.doc.medical_department
}
};
});
- if(frm.doc.consume_stock){
+
+ if (frm.doc.consume_stock) {
frm.set_indicator_formatter('item_code',
- function(doc) { return (doc.qty<=doc.actual_qty) ? "green" : "orange" ; });
+ function(doc) { return (doc.qty<=doc.actual_qty) ? 'green' : 'orange' ; });
}
- if (!frm.doc.__islocal && frm.doc.status == 'In Progress'){
+ if (frm.doc.docstatus == 1) {
+ if (frm.doc.status == 'In Progress') {
+ let btn_label = '';
+ let msg = '';
+ if (frm.doc.consume_stock) {
+ btn_label = __('Complete and Consume');
+ msg = __('Complete {0} and Consume Stock?', [frm.doc.name]);
+ } else {
+ btn_label = 'Complete';
+ msg = __('Complete {0}?', [frm.doc.name]);
+ }
- if(frm.doc.consume_stock){
- var btn_label = 'Complete and Consume';
- var msg = 'Complete '+frm.doc.name+' and Consume Stock?';
- }else{
- btn_label = 'Complete';
- msg = 'Complete '+frm.doc.name+'?';
- }
+ frm.add_custom_button(__(btn_label), function () {
+ frappe.confirm(
+ msg,
+ function() {
+ frappe.call({
+ method: 'complete_procedure',
+ doc: frm.doc,
+ callback: function(r) {
+ if (r.message) {
+ frappe.show_alert({
+ message: __('Stock Entry {0} created',
+ ['<a class="bold" href="#Form/Stock Entry/'+ r.message + '">' + r.message + '</a>']),
+ indicator: 'green'
+ });
+ frm.reload_doc();
+ }
+ }
+ });
+ }
+ );
+ }).addClass("btn-primary");
- frm.add_custom_button(__(btn_label), function () {
- frappe.confirm(
- __(msg),
- function(){
- frappe.call({
- doc: frm.doc,
- method: "complete",
- callback: function(r) {
- if(!r.exc){
+ } else if (frm.doc.status == 'Pending') {
+ frm.add_custom_button(__('Start'), function() {
+ frappe.call({
+ doc: frm.doc,
+ method: 'start_procedure',
+ callback: function(r) {
+ if (!r.exc) {
+ if (r.message == 'insufficient stock') {
+ let msg = __('Stock quantity to start the Procedure is not available in the Warehouse {0}. Do you want to record a Stock Entry?',
+ [frm.doc.warehouse.bold()]);
+ frappe.confirm(
+ msg,
+ function() {
+ frappe.call({
+ doc: frm.doc,
+ method: 'make_material_receipt',
+ callback: function(r) {
+ if (!r.exc) {
+ cur_frm.reload_doc();
+ let doclist = frappe.model.sync(r.message);
+ frappe.set_route('Form', doclist[0].doctype, doclist[0].name);
+ }
+ }
+ });
+ }
+ );
+ } else {
cur_frm.reload_doc();
}
}
- });
- }
- );
- });
- }else if (frm.doc.status == 'Draft') {
- frm.add_custom_button(__("Start"), function () {
- frappe.call({
- doc: frm.doc,
- method: "start",
- callback: function(r) {
- if(!r.exc){
- if(frm.doc.status == 'Draft'){
- frappe.confirm(
- __("Stock quantity to start procedure is not available in the warehouse. Do you want to record a Stock Transfer"),
- function(){
- frappe.call({
- doc: frm.doc,
- method: "make_material_transfer",
- callback: function(r) {
- if(!r.exc){
- cur_frm.reload_doc();
- var doclist = frappe.model.sync(r.message);
- frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
- }
- }
- });
- }
- );
- }else{
- cur_frm.reload_doc();
- }
}
- }
- });
- });
- }
- if (frm.doc.__islocal){
- frm.set_df_property("consumables", "hidden", 1);
- }else{
- frm.set_df_property("consumables", "hidden", 0);
+ });
+ }).addClass("btn-primary");
+ }
}
},
- onload: function(frm){
- if(frm.doc.status == 'Completed'){
- frm.set_df_property("items", "read_only", 1);
- }
- if(frm.is_new()) {
- frm.add_fetch("procedure_template", "medical_department", "medical_department");
- frm.set_value("start_time", null);
+
+ onload: function(frm) {
+ if (frm.is_new()) {
+ frm.add_fetch('procedure_template', 'medical_department', 'medical_department');
+ frm.set_value('start_time', null);
}
},
+
patient: function(frm) {
- if(frm.doc.patient){
+ if (frm.doc.patient) {
frappe.call({
- "method": "erpnext.healthcare.doctype.patient.patient.get_patient_detail",
+ 'method': 'erpnext.healthcare.doctype.patient.patient.get_patient_detail',
args: {
patient: frm.doc.patient
},
callback: function (data) {
- let age = "";
- if(data.message.dob){
+ let age = '';
+ if (data.message.dob) {
age = calculate_age(data.message.dob);
- }else if (data.message.age){
+ } else if (data.message.age) {
age = data.message.age;
- if(data.message.age_as_on){
- age = age+" as on "+data.message.age_as_on;
+ if (data.message.age_as_on) {
+ age = __('{0} as on {1}', [age, data.message.age_as_on]);
}
}
- frm.set_value("patient_age", age);
- frm.set_value("patient_sex", data.message.sex);
+ frm.set_value('patient_age', age);
+ frm.set_value('patient_sex', data.message.sex);
}
});
- }else{
- frm.set_value("patient_age", "");
- frm.set_value("patient_sex", "");
+ } else {
+ frm.set_value('patient_age', '');
+ frm.set_value('patient_sex', '');
}
},
+
appointment: function(frm) {
- if(frm.doc.appointment){
+ if (frm.doc.appointment) {
frappe.call({
- "method": "frappe.client.get",
+ 'method': 'frappe.client.get',
args: {
- doctype: "Patient Appointment",
+ doctype: 'Patient Appointment',
name: frm.doc.appointment
},
- callback: function (data) {
- frm.set_value("patient", data.message.patient);
- frm.set_value("procedure_template", data.message.procedure_template);
- frm.set_value("medical_department", data.message.department);
- frm.set_value("start_date", data.message.appointment_date);
- frm.set_value("start_time", data.message.appointment_time);
- frm.set_value("notes", data.message.notes);
- frm.set_value("service_unit", data.message.service_unit);
+ callback: function(data) {
+ frm.set_value('patient', data.message.patient);
+ frm.set_value('procedure_template', data.message.procedure_template);
+ frm.set_value('medical_department', data.message.department);
+ frm.set_value('start_date', data.message.appointment_date);
+ frm.set_value('start_time', data.message.appointment_time);
+ frm.set_value('notes', data.message.notes);
+ frm.set_value('service_unit', data.message.service_unit);
}
});
}
},
+
procedure_template: function(frm) {
- if(frm.doc.procedure_template){
+ if (frm.doc.procedure_template) {
frappe.call({
- "method": "frappe.client.get",
+ 'method': 'frappe.client.get',
args: {
- doctype: "Clinical Procedure Template",
+ doctype: 'Clinical Procedure Template',
name: frm.doc.procedure_template
},
callback: function (data) {
- frm.set_value("medical_department", data.message.medical_department);
- frm.set_value("consume_stock", data.message.consume_stock);
- if(!frm.doc.warehouse){
- frappe.call({
- method: "frappe.client.get_value",
- args: {
- doctype: "Stock Settings",
- fieldname: "default_warehouse"
- },
- callback: function (data) {
- frm.set_value("warehouse", data.message.default_warehouse);
- }
- });
- }
+ frm.set_value('medical_department', data.message.medical_department);
+ frm.set_value('consume_stock', data.message.consume_stock);
+ frm.events.set_warehouse(frm);
+ frm.events.set_procedure_consumables(frm);
}
});
- }else{
- frm.set_value("consume_stock", 0);
}
},
+
service_unit: function(frm) {
- if(frm.doc.service_unit){
+ if (frm.doc.service_unit) {
frappe.call({
- method: "frappe.client.get_value",
+ method: 'frappe.client.get_value',
args:{
- fieldname: "warehouse",
- doctype: "Healthcare Service Unit",
+ fieldname: 'warehouse',
+ doctype: 'Healthcare Service Unit',
filters:{name: frm.doc.service_unit},
},
callback: function(data) {
- if(data.message){
- frm.set_value("warehouse", data.message.warehouse);
+ if (data.message) {
+ frm.set_value('warehouse', data.message.warehouse);
}
}
});
}
},
+
practitioner: function(frm) {
- if(frm.doc.practitioner){
+ if (frm.doc.practitioner) {
frappe.call({
- "method": "frappe.client.get",
+ 'method': 'frappe.client.get',
args: {
- doctype: "Healthcare Practitioner",
+ doctype: 'Healthcare Practitioner',
name: frm.doc.practitioner
},
callback: function (data) {
- frappe.model.set_value(frm.doctype,frm.docname, "medical_department",data.message.department);
+ frappe.model.set_value(frm.doctype,frm.docname, 'medical_department',data.message.department);
}
});
}
+ },
+
+ set_warehouse: function(frm) {
+ if (!frm.doc.warehouse) {
+ frappe.call({
+ method: 'frappe.client.get_value',
+ args: {
+ doctype: 'Stock Settings',
+ fieldname: 'default_warehouse'
+ },
+ callback: function (data) {
+ frm.set_value('warehouse', data.message.default_warehouse);
+ }
+ });
+ }
+ },
+
+ set_procedure_consumables: function(frm) {
+ frappe.call({
+ method: 'erpnext.healthcare.doctype.clinical_procedure.clinical_procedure.get_procedure_consumables',
+ args: {
+ procedure_template: frm.doc.procedure_template
+ },
+ callback: function(data) {
+ if (data.message) {
+ frm.doc.items = [];
+ $.each(data.message, function(i, v) {
+ let item = frm.add_child('items');
+ item.item_code = v.item_code;
+ item.item_name = v.item_name;
+ item.uom = v.uom;
+ item.stock_uom = v.stock_uom;
+ item.qty = flt(v.qty);
+ item.transfer_qty = v.transfer_qty;
+ item.conversion_factor = v.conversion_factor;
+ item.invoice_separately_as_consumables = v.invoice_separately_as_consumables;
+ item.batch_no = v.batch_no;
+ });
+ refresh_field('items');
+ }
+ }
+ });
}
+
});
-cur_frm.set_query("procedure_template", function(doc) {
+cur_frm.set_query('procedure_template', function(doc) {
return {
filters: {
'medical_department': doc.medical_department
@@ -249,57 +290,51 @@
};
});
-cur_frm.set_query("appointment", function() {
- return {
- filters: {
- status:['in',["Open"]]
- }
- };
-});
-
frappe.ui.form.on('Clinical Procedure Item', {
- qty: function(frm, cdt, cdn){
- var d = locals[cdt][cdn];
- frappe.model.set_value(cdt, cdn, "transfer_qty", d.qty*d.conversion_factor);
+ qty: function(frm, cdt, cdn) {
+ let d = locals[cdt][cdn];
+ frappe.model.set_value(cdt, cdn, 'transfer_qty', d.qty*d.conversion_factor);
},
- uom: function(doc, cdt, cdn){
- var d = locals[cdt][cdn];
- if(d.uom && d.item_code){
+
+ uom: function(doc, cdt, cdn) {
+ let d = locals[cdt][cdn];
+ if (d.uom && d.item_code) {
return frappe.call({
- method: "erpnext.stock.doctype.stock_entry.stock_entry.get_uom_details",
+ method: 'erpnext.stock.doctype.stock_entry.stock_entry.get_uom_details',
args: {
item_code: d.item_code,
uom: d.uom,
qty: d.qty
},
callback: function(r) {
- if(r.message) {
+ if (r.message) {
frappe.model.set_value(cdt, cdn, r.message);
}
}
});
}
},
+
item_code: function(frm, cdt, cdn) {
- var d = locals[cdt][cdn];
+ let d = locals[cdt][cdn];
let args = null;
- if(d.item_code) {
+ if (d.item_code) {
args = {
- 'doctype' : "Clinical Procedure",
+ 'doctype' : 'Clinical Procedure',
'item_code' : d.item_code,
'company' : frm.doc.company,
'warehouse': frm.doc.warehouse
};
return frappe.call({
- method: "erpnext.stock.get_item_details.get_item_details",
+ method: 'erpnext.healthcare.doctype.clinical_procedure_template.clinical_procedure_template.get_item_details',
args: {args: args},
callback: function(r) {
- if(r.message) {
- frappe.model.set_value(cdt, cdn, "item_name", r.message.item_name);
- frappe.model.set_value(cdt, cdn, "stock_uom", r.message.stock_uom);
- frappe.model.set_value(cdt, cdn, "conversion_factor", r.message.conversion_factor);
- frappe.model.set_value(cdt, cdn, "actual_qty", r.message.actual_qty);
- refresh_field("items");
+ if (r.message) {
+ let d = locals[cdt][cdn];
+ $.each(r.message, function(k, v) {
+ d[k] = v;
+ });
+ refresh_field('items');
}
}
});
@@ -307,16 +342,16 @@
}
});
-var calculate_age = function(birth) {
- var ageMS = Date.parse(Date()) - Date.parse(birth);
- var age = new Date();
+let calculate_age = function(birth) {
+ let ageMS = Date.parse(Date()) - Date.parse(birth);
+ let age = new Date();
age.setTime(ageMS);
- var years = age.getFullYear() - 1970;
- return years + " Year(s) " + age.getMonth() + " Month(s) " + age.getDate() + " Day(s)";
+ let years = age.getFullYear() - 1970;
+ return years + ' Year(s) ' + age.getMonth() + ' Month(s) ' + age.getDate() + ' Day(s)';
};
// List Stock items
-cur_frm.set_query("item_code", "items", function() {
+cur_frm.set_query('item_code', 'items', function() {
return {
filters: {
is_stock_item:1
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json
index 3097ba3..3c936bb 100644
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json
@@ -1,955 +1,267 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "autoname": "naming_series:",
- "beta": 1,
- "creation": "2017-04-07 12:52:43.542429",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "actions": [],
+ "autoname": "naming_series:",
+ "beta": 1,
+ "creation": "2017-04-07 12:52:43.542429",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "inpatient_record",
+ "naming_series",
+ "procedure_template",
+ "appointment",
+ "patient",
+ "patient_sex",
+ "patient_age",
+ "prescription",
+ "medical_department",
+ "practitioner",
+ "column_break_7",
+ "status",
+ "service_unit",
+ "warehouse",
+ "start_date",
+ "start_time",
+ "sample",
+ "invoiced",
+ "notes",
+ "company",
+ "consumables_section",
+ "consume_stock",
+ "items",
+ "section_break_24",
+ "invoice_separately_as_consumables",
+ "consumption_invoiced",
+ "consumable_total_amount",
+ "column_break_27",
+ "consumption_details",
+ "amended_from"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "patient.inpatient_record",
- "fieldname": "inpatient_record",
- "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": "Inpatient Record",
- "length": 0,
- "no_copy": 0,
- "options": "Inpatient Record",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "patient.inpatient_record",
+ "fieldname": "inpatient_record",
+ "fieldtype": "Link",
+ "label": "Inpatient Record",
+ "options": "Inpatient Record",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "fieldname": "naming_series",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Series",
- "length": 0,
- "no_copy": 0,
- "options": "HLC-CPR-.YYYY.-",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "naming_series",
+ "fieldtype": "Select",
+ "label": "Series",
+ "options": "HLC-CPR-.YYYY.-"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "appointment",
- "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": "Appointment",
- "length": 0,
- "no_copy": 0,
- "options": "Patient Appointment",
- "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": 1,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "appointment",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Appointment",
+ "options": "Patient Appointment"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "inpatient_record.patient",
- "fieldname": "patient",
- "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": "Patient",
- "length": 0,
- "no_copy": 0,
- "options": "Patient",
- "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": 1,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "inpatient_record.patient",
+ "fieldname": "patient",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Patient",
+ "options": "Patient",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "patient_age",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Age",
- "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": 1,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "patient_age",
+ "fieldtype": "Data",
+ "label": "Age",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "patient_sex",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Gender",
- "length": 0,
- "no_copy": 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": 1,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "patient_sex",
+ "fieldtype": "Link",
+ "label": "Gender",
+ "options": "Gender",
+ "read_only": 1,
+ "set_only_once": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "prescription",
- "fieldtype": "Link",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Procedure Prescription",
- "length": 0,
- "no_copy": 0,
- "options": "Procedure Prescription",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "prescription",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "label": "Procedure Prescription",
+ "options": "Procedure Prescription"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "medical_department",
- "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": "Medical Department",
- "length": 0,
- "no_copy": 0,
- "options": "Medical Department",
- "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": 1,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "medical_department",
+ "fieldtype": "Link",
+ "label": "Medical Department",
+ "options": "Medical Department"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "practitioner",
- "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": "Healthcare Practitioner",
- "length": 0,
- "no_copy": 0,
- "options": "Healthcare Practitioner",
- "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": 1,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "practitioner",
+ "fieldtype": "Link",
+ "label": "Healthcare Practitioner",
+ "options": "Healthcare Practitioner"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_7",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_7",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "procedure_template",
- "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": "Procedure Template",
- "length": 0,
- "no_copy": 0,
- "options": "Clinical Procedure Template",
- "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": 1,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "procedure_template",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Procedure Template",
+ "options": "Clinical Procedure Template",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "service_unit",
- "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": "Service Unit",
- "length": 0,
- "no_copy": 0,
- "options": "Healthcare Service Unit",
- "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": 1,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "service_unit",
+ "fieldtype": "Link",
+ "label": "Service Unit",
+ "options": "Healthcare Service Unit",
+ "set_only_once": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "warehouse",
- "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": "Warehouse",
- "length": 0,
- "no_copy": 0,
- "options": "Warehouse",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 1,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "warehouse",
+ "fieldtype": "Link",
+ "label": "Warehouse",
+ "mandatory_depends_on": "eval: doc.consume_stock == 1",
+ "options": "Warehouse"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "Today",
- "fieldname": "start_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Start Date",
- "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": 1,
- "translatable": 0,
- "unique": 0
- },
+ "default": "Today",
+ "fieldname": "start_date",
+ "fieldtype": "Date",
+ "label": "Start Date"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "start_time",
- "fieldtype": "Time",
- "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": "Time",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "start_time",
+ "fieldtype": "Time",
+ "label": "Start Time"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sample",
- "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": "Sample",
- "length": 0,
- "no_copy": 0,
- "options": "Sample Collection",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "sample",
+ "fieldtype": "Link",
+ "label": "Sample",
+ "options": "Sample Collection"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "invoiced",
- "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": "Invoiced",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "invoiced",
+ "fieldtype": "Check",
+ "label": "Invoiced",
+ "no_copy": 1,
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "notes",
- "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": "Notes",
- "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": 1,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "notes",
+ "fieldtype": "Small Text",
+ "label": "Notes",
+ "set_only_once": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "company",
- "fieldtype": "Link",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Company",
- "length": 0,
- "no_copy": 0,
- "options": "Company",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "label": "Company",
+ "options": "Company"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "consume_stock",
- "fieldtype": "Check",
- "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": "Consume Stock",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "consume_stock",
+ "fieldtype": "Check",
+ "label": "Consume Stock"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:doc.consume_stock == 1",
- "fieldname": "consumables",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Consumables",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "items",
+ "fieldtype": "Table",
+ "label": "Consumables",
+ "options": "Clinical Procedure Item"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "items",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Consumables",
- "length": 0,
- "no_copy": 0,
- "options": "Clinical Procedure Item",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "invoice_separately_as_consumables",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "label": "Invoice Consumables Separately",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "invoice_separately_as_consumables",
- "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": "Consumables Invoice Separately",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "depends_on": "invoice_separately_as_consumables",
+ "fieldname": "consumable_total_amount",
+ "fieldtype": "Currency",
+ "label": "Consumable Total Amount",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "invoice_separately_as_consumables",
- "fieldname": "consumable_total_amount",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Consumable Total Amount",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "depends_on": "invoice_separately_as_consumables",
+ "fieldname": "consumption_details",
+ "fieldtype": "Small Text",
+ "label": "Consumption Details"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "invoice_separately_as_consumables",
- "fieldname": "consumption_details",
- "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": "Consumption Details",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "depends_on": "invoice_separately_as_consumables",
+ "fieldname": "consumption_invoiced",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "label": "Consumption Invoiced",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "depends_on": "invoice_separately_as_consumables",
- "fieldname": "consumption_invoiced",
- "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": "Consumption Invoiced",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Status",
+ "options": "Draft\nSubmitted\nCancelled\nIn Progress\nCompleted\nPending",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "fieldname": "status",
- "fieldtype": "Select",
- "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": "Status",
- "length": 0,
- "no_copy": 0,
- "options": "Draft\nIn Progress\nCompleted\nPending\nCancelled",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "label": "Amended From",
+ "no_copy": 1,
+ "options": "Clinical Procedure",
+ "print_hide": 1,
+ "read_only": 1
+ },
+ {
+ "fieldname": "consumables_section",
+ "fieldtype": "Section Break",
+ "label": "Consumables"
+ },
+ {
+ "fieldname": "column_break_27",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "section_break_24",
+ "fieldtype": "Section Break"
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-08-21 14:44:49.438611",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Clinical Procedure",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "is_submittable": 1,
+ "links": [],
+ "modified": "2020-03-02 11:44:27.970651",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Clinical Procedure",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Nursing User",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Nursing User",
+ "share": 1,
"write": 1
}
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1,
- "track_seen": 0,
- "track_views": 0
-}
+ ],
+ "restrict_to_domain": "Healthcare",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
index 7c6f4d5..db3afc8 100644
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
@@ -6,88 +6,101 @@
import frappe
from frappe import _
from frappe.model.document import Document
-from frappe.utils import cint, flt, nowdate, nowtime, cstr
+from frappe.utils import flt, nowdate, nowtime, cstr
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_account
from erpnext.healthcare.doctype.lab_test.lab_test import create_sample_doc
from erpnext.stock.stock_ledger import get_previous_sle
from erpnext.stock.get_item_details import get_item_details
+from frappe.model.mapper import get_mapped_doc
class ClinicalProcedure(Document):
def validate(self):
- if self.consume_stock and not self.status == 'Draft':
- if not self.warehouse:
- frappe.throw(_("Set warehouse for Procedure {0} ").format(self.name))
+ self.set_status()
+ if self.consume_stock:
self.set_actual_qty()
if self.items:
self.invoice_separately_as_consumables = False
for item in self.items:
- if item.invoice_separately_as_consumables == 1:
+ if item.invoice_separately_as_consumables:
self.invoice_separately_as_consumables = True
def before_insert(self):
if self.consume_stock:
- set_stock_items(self, self.procedure_template, "Clinical Procedure Template")
- self.set_actual_qty();
+ self.set_actual_qty()
def after_insert(self):
if self.prescription:
- frappe.db.set_value("Procedure Prescription", self.prescription, "procedure_created", 1)
+ frappe.db.set_value('Procedure Prescription', self.prescription, 'procedure_created', 1)
if self.appointment:
- frappe.db.set_value("Patient Appointment", self.appointment, "status", "Closed")
- template = frappe.get_doc("Clinical Procedure Template", self.procedure_template)
+ frappe.db.set_value('Patient Appointment', self.appointment, 'status', 'Closed')
+ template = frappe.get_doc('Clinical Procedure Template', self.procedure_template)
if template.sample:
- patient = frappe.get_doc("Patient", self.patient)
+ patient = frappe.get_doc('Patient', self.patient)
sample_collection = create_sample_doc(template, patient, None)
- frappe.db.set_value("Clinical Procedure", self.name, "sample", sample_collection.name)
+ frappe.db.set_value('Clinical Procedure', self.name, 'sample', sample_collection.name)
self.reload()
- def complete(self):
+ def set_status(self):
+ if self.docstatus == 0:
+ self.status = 'Draft'
+ elif self.docstatus == 1:
+ if self.status not in ['In Progress', 'Completed']:
+ self.status = 'Pending'
+ elif self.docstatus == 2:
+ self.status = 'Cancelled'
+
+ def complete_procedure(self):
if self.consume_stock and self.items:
- create_stock_entry(self)
- frappe.db.set_value("Clinical Procedure", self.name, "status", 'Completed')
+ stock_entry = make_stock_entry(self)
if self.items:
consumable_total_amount = 0
consumption_details = False
- for item in self.items:
- if item.invoice_separately_as_consumables:
- price_list, price_list_currency = frappe.db.get_values("Price List", {"selling": 1}, ['name', 'currency'])[0]
- args = {
- 'doctype': "Sales Invoice",
- 'item_code': item.item_code,
- 'company': self.company,
- 'warehouse': self.warehouse,
- 'customer': frappe.db.get_value("Patient", self.patient, "customer"),
- 'selling_price_list': price_list,
- 'price_list_currency': price_list_currency,
- 'plc_conversion_rate': 1.0,
- 'conversion_rate': 1.0
- }
- item_details = get_item_details(args)
- item_price = item_details.price_list_rate * item.transfer_qty
- item_consumption_details = item_details.item_name+"\t"+str(item.qty)+" "+item.uom+"\t"+str(item_price)
- consumable_total_amount += item_price
- if not consumption_details:
- consumption_details = "Clinical Procedure ("+self.name+"):\n\t"+item_consumption_details
- else:
- consumption_details += "\n\t"+item_consumption_details
- if consumable_total_amount > 0:
- frappe.db.set_value("Clinical Procedure", self.name, "consumable_total_amount", consumable_total_amount)
- frappe.db.set_value("Clinical Procedure", self.name, "consumption_details", consumption_details)
+ customer = frappe.db.get_value('Patient', self.patient, 'customer')
+ if customer:
+ for item in self.items:
+ if item.invoice_separately_as_consumables:
+ price_list, price_list_currency = frappe.db.get_values('Price List', {'selling': 1}, ['name', 'currency'])[0]
+ args = {
+ 'doctype': 'Sales Invoice',
+ 'item_code': item.item_code,
+ 'company': self.company,
+ 'warehouse': self.warehouse,
+ 'customer': customer,
+ 'selling_price_list': price_list,
+ 'price_list_currency': price_list_currency,
+ 'plc_conversion_rate': 1.0,
+ 'conversion_rate': 1.0
+ }
+ item_details = get_item_details(args)
+ item_price = item_details.price_list_rate * item.qty
+ item_consumption_details = item_details.item_name + ' ' + str(item.qty) + ' ' + item.uom + ' ' + str(item_price)
+ consumable_total_amount += item_price
+ if not consumption_details:
+ consumption_details = _('Clinical Procedure ({0}):').format(self.name)
+ consumption_details += '\n\t' + item_consumption_details
+ if consumable_total_amount > 0:
+ frappe.db.set_value('Clinical Procedure', self.name, 'consumable_total_amount', consumable_total_amount)
+ frappe.db.set_value('Clinical Procedure', self.name, 'consumption_details', consumption_details)
+ else:
+ frappe.throw(_('Please set Customer in Patient {0}').format(frappe.bold(self.patient)), title=_('Customer Not Found'))
- def start(self):
+ frappe.db.set_value('Clinical Procedure', self.name, 'status', 'Completed')
+ if self.consume_stock and self.items:
+ return stock_entry
+
+ def start_procedure(self):
allow_start = self.set_actual_qty()
if allow_start:
- self.status = 'In Progress'
+ self.db_set('status', 'In Progress')
insert_clinical_procedure_to_medical_record(self)
- else:
- self.status = 'Draft'
- self.save()
+ return 'success'
+ return 'insufficient stock'
def set_actual_qty(self):
- allow_negative_stock = cint(frappe.db.get_value("Stock Settings", None, "allow_negative_stock"))
+ allow_negative_stock = frappe.db.get_single_value('Stock Settings', 'allow_negative_stock')
allow_start = True
for d in self.get('items'):
@@ -95,15 +108,16 @@
# validate qty
if not allow_negative_stock and d.actual_qty < d.qty:
allow_start = False
+ break
return allow_start
- def make_material_transfer(self):
- stock_entry = frappe.new_doc("Stock Entry")
+ def make_material_receipt(self, submit=False):
+ stock_entry = frappe.new_doc('Stock Entry')
- stock_entry.purpose = "Material Transfer"
+ stock_entry.stock_entry_type = 'Material Receipt'
stock_entry.to_warehouse = self.warehouse
- expense_account = get_account(None, "expense_account", "Healthcare Settings", self.company)
+ expense_account = get_account(None, 'expense_account', 'Healthcare Settings', self.company)
for item in self.items:
if item.qty > item.actual_qty:
se_child = stock_entry.append('items')
@@ -111,7 +125,7 @@
se_child.item_name = item.item_name
se_child.uom = item.uom
se_child.stock_uom = item.stock_uom
- se_child.qty = flt(item.qty-item.actual_qty)
+ se_child.qty = flt(item.qty - item.actual_qty)
se_child.t_warehouse = self.warehouse
# in stock uom
se_child.transfer_qty = flt(item.transfer_qty)
@@ -119,104 +133,130 @@
cost_center = frappe.get_cached_value('Company', self.company, 'cost_center')
se_child.cost_center = cost_center
se_child.expense_account = expense_account
+ if submit:
+ stock_entry.submit()
+ return stock_entry
return stock_entry.as_dict()
-@frappe.whitelist()
+
def get_stock_qty(item_code, warehouse):
return get_previous_sle({
- "item_code": item_code,
- "warehouse": warehouse,
- "posting_date": nowdate(),
- "posting_time": nowtime()
- }).get("qty_after_transaction") or 0
+ 'item_code': item_code,
+ 'warehouse': warehouse,
+ 'posting_date': nowdate(),
+ 'posting_time': nowtime()
+ }).get('qty_after_transaction') or 0
+
+
+@frappe.whitelist()
+def get_procedure_consumables(procedure_template):
+ return get_items('Clinical Procedure Item', procedure_template, 'Clinical Procedure Template')
+
@frappe.whitelist()
def set_stock_items(doc, stock_detail_parent, parenttype):
- item_dict = get_item_dict("Clinical Procedure Item", stock_detail_parent, parenttype)
+ items = get_items('Clinical Procedure Item', stock_detail_parent, parenttype)
- for d in item_dict:
+ for item in items:
se_child = doc.append('items')
- se_child.item_code = d["item_code"]
- se_child.item_name = d["item_name"]
- se_child.uom = d["uom"]
- se_child.stock_uom = d["stock_uom"]
- se_child.qty = flt(d["qty"])
+ se_child.item_code = item.item_code
+ se_child.item_name = item.item_name
+ se_child.uom = item.uom
+ se_child.stock_uom = item.stock_uom
+ se_child.qty = flt(item.qty)
# in stock uom
- se_child.transfer_qty = flt(d["transfer_qty"])
- se_child.conversion_factor = flt(d["conversion_factor"])
- if d["batch_no"]:
- se_child.batch_no = d["batch_no"]
- if parenttype == "Clinical Procedure Template":
- se_child.invoice_separately_as_consumables = d["invoice_separately_as_consumables"]
+ se_child.transfer_qty = flt(item.transfer_qty)
+ se_child.conversion_factor = flt(item.conversion_factor)
+ if item.batch_no:
+ se_child.batch_no = item.batch_no
+ if parenttype == 'Clinical Procedure Template':
+ se_child.invoice_separately_as_consumables = item.invoice_separately_as_consumables
+
return doc
-def get_item_dict(table, parent, parenttype):
- query = """select * from `tab{table}` where parent = '{parent}' and parenttype = '{parenttype}' """
- return frappe.db.sql(query.format(table=table, parent=parent, parenttype=parenttype), as_dict=True)
+def get_items(table, parent, parenttype):
+ items = frappe.db.get_all(table, filters={
+ 'parent': parent,
+ 'parenttype': parenttype
+ }, fields=['*'])
-def create_stock_entry(doc):
- stock_entry = frappe.new_doc("Stock Entry")
- stock_entry = set_stock_items(stock_entry, doc.name, "Clinical Procedure")
- stock_entry.purpose = "Material Issue"
+ return items
+
+
+@frappe.whitelist()
+def make_stock_entry(doc):
+ stock_entry = frappe.new_doc('Stock Entry')
+ stock_entry = set_stock_items(stock_entry, doc.name, 'Clinical Procedure')
+ stock_entry.stock_entry_type = 'Material Issue'
stock_entry.from_warehouse = doc.warehouse
stock_entry.company = doc.company
- expense_account = get_account(None, "expense_account", "Healthcare Settings", doc.company)
+ expense_account = get_account(None, 'expense_account', 'Healthcare Settings', doc.company)
for item_line in stock_entry.items:
cost_center = frappe.get_cached_value('Company', doc.company, 'cost_center')
- #item_line.s_warehouse = warehouse #deaful source warehouse set, stock entry to copy to lines
item_line.cost_center = cost_center
- #if not expense_account:
- # expense_account = frappe.db.get_value("Item", item_line.item_code, "expense_account")
item_line.expense_account = expense_account
- stock_entry.insert(ignore_permissions = True)
+ stock_entry.save(ignore_permissions=True)
stock_entry.submit()
+ return stock_entry.name
+
@frappe.whitelist()
-def create_procedure(appointment):
- appointment = frappe.get_doc("Patient Appointment",appointment)
- procedure = frappe.new_doc("Clinical Procedure")
- procedure.appointment = appointment.name
- procedure.patient = appointment.patient
- procedure.patient_age = appointment.patient_age
- procedure.patient_sex = appointment.patient_sex
- procedure.procedure_template = appointment.procedure_template
- procedure.prescription = appointment.procedure_prescription
- procedure.practitioner = appointment.practitioner
- procedure.invoiced = appointment.invoiced
- procedure.medical_department = appointment.department
- procedure.start_date = appointment.appointment_date
- procedure.start_time = appointment.appointment_time
- procedure.notes = appointment.notes
- procedure.service_unit = appointment.service_unit
- procedure.company = appointment.company
- consume_stock = frappe.db.get_value("Clinical Procedure Template", appointment.procedure_template, "consume_stock")
- if consume_stock == 1:
- procedure.consume_stock = True
- warehouse = False
- if appointment.service_unit:
- warehouse = frappe.db.get_value("Healthcare Service Unit", appointment.service_unit, "warehouse")
- if not warehouse:
- warehouse = frappe.db.get_value("Stock Settings", None, "default_warehouse")
- if warehouse:
- procedure.warehouse = warehouse
- return procedure.as_dict()
+def make_procedure(source_name, target_doc=None):
+ def set_missing_values(source, target):
+ consume_stock = frappe.db.get_value('Clinical Procedure Template', source.procedure_template, 'consume_stock')
+ if consume_stock:
+ target.consume_stock = 1
+ warehouse = None
+ if source.service_unit:
+ warehouse = frappe.db.get_value('Healthcare Service Unit', source.service_unit, 'warehouse')
+ if not warehouse:
+ warehouse = frappe.db.get_value('Stock Settings', None, 'default_warehouse')
+ if warehouse:
+ target.warehouse = warehouse
+
+ set_stock_items(target, source.procedure_template, 'Clinical Procedure Template')
+
+ doc = get_mapped_doc('Patient Appointment', source_name, {
+ 'Patient Appointment': {
+ 'doctype': 'Clinical Procedure',
+ 'field_map': [
+ ['appointment', 'name'],
+ ['patient', 'patient'],
+ ['patient_age', 'patient_age'],
+ ['patient_sex', 'patient_sex'],
+ ['procedure_template', 'procedure_template'],
+ ['prescription', 'procedure_prescription'],
+ ['practitioner', 'practitioner'],
+ ['medical_department', 'department'],
+ ['start_date', 'appointment_date'],
+ ['start_time', 'appointment_time'],
+ ['notes', 'notes'],
+ ['service_unit', 'service_unit'],
+ ['company', 'company'],
+ ['invoiced', 'invoiced']
+ ]
+ }
+ }, target_doc, set_missing_values)
+
+ return doc
+
def insert_clinical_procedure_to_medical_record(doc):
subject = cstr(doc.procedure_template)
if doc.practitioner:
- subject += " "+doc.practitioner
+ subject += ' ' + doc.practitioner
if subject and doc.notes:
- subject += "<br/>"+doc.notes
+ subject += '<br/>' + doc.notes
- medical_record = frappe.new_doc("Patient Medical Record")
+ medical_record = frappe.new_doc('Patient Medical Record')
medical_record.patient = doc.patient
medical_record.subject = subject
- medical_record.status = "Open"
+ medical_record.status = 'Open'
medical_record.communication_date = doc.start_date
- medical_record.reference_doctype = "Clinical Procedure"
+ medical_record.reference_doctype = 'Clinical Procedure'
medical_record.reference_name = doc.name
medical_record.reference_owner = doc.owner
medical_record.save(ignore_permissions=True)
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure_list.js b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure_list.js
new file mode 100644
index 0000000..c8601f9
--- /dev/null
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure_list.js
@@ -0,0 +1,11 @@
+frappe.listview_settings['Clinical Procedure'] = {
+ get_indicator: function(doc) {
+ var colors = {
+ 'Completed': 'green',
+ 'In Progress': 'orange',
+ 'Pending': 'orange',
+ 'Cancelled': 'grey'
+ };
+ return [__(doc.status), colors[doc.status], 'status,=,' + doc.status];
+ }
+};
diff --git a/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py b/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py
index 09059e1..207351f 100644
--- a/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py
+++ b/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py
@@ -4,6 +4,60 @@
from __future__ import unicode_literals
import unittest
+import frappe
+from erpnext.healthcare.doctype.patient_appointment.test_patient_appointment import create_healthcare_docs, create_clinical_procedure_template
class TestClinicalProcedure(unittest.TestCase):
- pass
+ def test_procedure_template_item(self):
+ patient, medical_department, practitioner = create_healthcare_docs()
+ procedure_template = create_clinical_procedure_template()
+ self.assertTrue(frappe.db.exists('Item', procedure_template.item))
+
+ procedure_template.disabled = 1
+ procedure_template.save()
+ self.assertEquals(frappe.db.get_value('Item', procedure_template.item, 'disabled'), 1)
+
+ def test_consumables(self):
+ patient, medical_department, practitioner = create_healthcare_docs()
+ procedure_template = create_clinical_procedure_template()
+ procedure_template.allow_stock_consumption = 1
+ consumable = create_consumable()
+ procedure_template.append('items', {
+ 'item_code': consumable.item_code,
+ 'qty': 1,
+ 'uom': consumable.stock_uom,
+ 'stock_uom': consumable.stock_uom
+ })
+ procedure_template.save()
+ procedure = create_procedure(procedure_template, patient, practitioner)
+ result = procedure.start_procedure()
+ if result == 'insufficient stock':
+ procedure.make_material_receipt(submit=True)
+ result = procedure.start_procedure()
+ self.assertEqual(procedure.status, 'In Progress')
+ result = procedure.complete_procedure()
+ # check consumption
+ self.assertTrue(frappe.db.exists('Stock Entry', result))
+
+
+def create_consumable():
+ if frappe.db.exists('Item', 'Syringe'):
+ return frappe.get_doc('Item', 'Syringe')
+ consumable = frappe.new_doc('Item')
+ consumable.item_code = 'Syringe'
+ consumable.item_group = '_Test Item Group'
+ consumable.stock_uom = 'Nos'
+ consumable.valuation_rate = 5.00
+ consumable.save()
+ return consumable
+
+def create_procedure(procedure_template, patient, practitioner):
+ procedure = frappe.new_doc('Clinical Procedure')
+ procedure.procedure_template = procedure_template.name
+ procedure.patient = patient
+ procedure.practitioner = practitioner
+ procedure.consume_stock = procedure_template.allow_stock_consumption
+ procedure.items = procedure_template.items
+ procedure.warehouse = frappe.db.get_single_value('Stock Settings', 'default_warehouse')
+ procedure.submit()
+ return procedure
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json b/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json
index 75151b1..a7dde0b 100644
--- a/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json
+++ b/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json
@@ -1,431 +1,123 @@
{
- "allow_copy": 0,
- "allow_events_in_timeline": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 1,
- "creation": "2017-10-05 16:15:10.876952",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "actions": [],
+ "beta": 1,
+ "creation": "2017-10-05 16:15:10.876952",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "item_code",
+ "item_name",
+ "qty",
+ "barcode",
+ "uom",
+ "invoice_separately_as_consumables",
+ "column_break_5",
+ "batch_no",
+ "conversion_factor",
+ "stock_uom",
+ "transfer_qty",
+ "actual_qty"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 1,
- "collapsible": 0,
- "columns": 3,
- "fieldname": "item_code",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 1,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Item",
- "length": 0,
- "no_copy": 0,
- "options": "Item",
- "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": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "bold": 1,
+ "columns": 3,
+ "fieldname": "item_code",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "in_global_search": 1,
+ "in_list_view": 1,
+ "label": "Item",
+ "options": "Item",
+ "reqd": 1,
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "barcode",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Barcode",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "barcode",
+ "fieldtype": "Data",
+ "label": "Barcode"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "item_name",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Item Name",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "item_name",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Item Name",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "qty",
- "fieldtype": "Float",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Quantity",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "qty",
+ "fieldtype": "Float",
+ "in_list_view": 1,
+ "label": "Quantity",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "uom",
- "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": "UOM",
- "length": 0,
- "no_copy": 0,
- "options": "UOM",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "uom",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "UOM",
+ "options": "UOM",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "invoice_separately_as_consumables",
- "fieldtype": "Check",
- "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": "Invoice Separately as Consumables",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "invoice_separately_as_consumables",
+ "fieldtype": "Check",
+ "in_list_view": 1,
+ "label": "Invoice Separately as Consumables"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_5",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_5",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "batch_no",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Batch",
- "length": 0,
- "no_copy": 0,
- "options": "Batch",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "batch_no",
+ "fieldtype": "Link",
+ "label": "Batch",
+ "options": "Batch"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "conversion_factor",
- "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": "Conversion Factor",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "conversion_factor",
+ "fieldtype": "Float",
+ "label": "Conversion Factor",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "stock_uom",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Stock UOM",
- "length": 0,
- "no_copy": 0,
- "options": "UOM",
- "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,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "stock_uom",
+ "fieldtype": "Link",
+ "label": "Stock UOM",
+ "options": "UOM",
+ "read_only": 1,
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "transfer_qty",
- "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": "Transfer Qty",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "transfer_qty",
+ "fieldtype": "Float",
+ "label": "Transfer Qty",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "actual_qty",
- "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": "Actual Qty (at source/target)",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "fieldname": "actual_qty",
+ "fieldtype": "Float",
+ "label": "Actual Qty (at source/target)",
+ "no_copy": 1,
+ "print_hide": 1,
+ "read_only": 1,
+ "search_index": 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": "2018-11-04 03:33:16.833884",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Clinical Procedure Item",
- "name_case": "",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1,
- "track_seen": 0,
- "track_views": 0
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-03-01 15:34:54.226722",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Clinical Procedure Item",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "restrict_to_domain": "Healthcare",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.js b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.js
index 583728d..57f4cdf 100644
--- a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.js
+++ b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.js
@@ -3,170 +3,141 @@
frappe.ui.form.on('Clinical Procedure Template', {
template: function(frm) {
- if(!frm.doc.item_code)
- frm.set_value("item_code", frm.doc.template);
- if(!frm.doc.description)
- frm.set_value("description", frm.doc.template);
+ if (!frm.doc.item_code)
+ frm.set_value('item_code', frm.doc.template);
+ if (!frm.doc.description)
+ frm.set_value('description', frm.doc.template);
mark_change_in_item(frm);
},
+
rate: function(frm) {
mark_change_in_item(frm);
},
+
is_billable: function (frm) {
mark_change_in_item(frm);
},
+
item_group: function(frm) {
mark_change_in_item(frm);
},
+
description: function(frm) {
mark_change_in_item(frm);
},
+
medical_department: function(frm) {
mark_change_in_item(frm);
},
+
refresh: function(frm) {
- frm.fields_dict["items"].grid.set_column_disp("barcode", false);
- frm.fields_dict["items"].grid.set_column_disp("batch_no", false);
- cur_frm.set_df_property("item_code", "read_only", frm.doc.__islocal ? 0 : 1);
- if(!frm.doc.__islocal) {
+ frm.fields_dict['items'].grid.set_column_disp('barcode', false);
+ frm.fields_dict['items'].grid.set_column_disp('batch_no', false);
+
+ if (!frm.doc.__islocal) {
cur_frm.add_custom_button(__('Change Item Code'), function() {
change_template_code(frm.doc);
- } );
- if(frm.doc.disabled == 1){
- cur_frm.add_custom_button(__('Enable Template'), function() {
- enable_template(frm.doc);
- } );
- }
- else{
- cur_frm.add_custom_button(__('Disable Template'), function() {
- disable_template(frm.doc);
- } );
- }
+ });
}
}
});
-var mark_change_in_item = function(frm) {
- if(!frm.doc.__islocal){
+let mark_change_in_item = function(frm) {
+ if (!frm.doc.__islocal) {
frm.doc.change_in_item = 1;
}
};
-var disable_template = function(doc){
- frappe.call({
- method: "erpnext.healthcare.doctype.clinical_procedure_template.clinical_procedure_template.disable_enable_template",
- args: {status: 1, name: doc.name, item_code: doc.item_code, is_billable: doc.is_billable},
- callback: function(){
- cur_frm.reload_doc();
- }
- });
-};
-
-var enable_template = function(doc){
- frappe.call({
- method: "erpnext.healthcare.doctype.clinical_procedure_template.clinical_procedure_template.disable_enable_template",
- args: {status: 0, name: doc.name, item_code: doc.item_code, is_billable: doc.is_billable},
- callback: function(){
- cur_frm.reload_doc();
- }
- });
-};
-
-
-var change_template_code = function(doc){
- var d = new frappe.ui.Dialog({
- title:__("Change Template Code"),
+let change_template_code = function(doc) {
+ let d = new frappe.ui.Dialog({
+ title:__('Change Item Code'),
fields:[
{
- "fieldtype": "Data",
- "label": "Template Code",
- "fieldname": "Item Code",
- reqd:1
- },
- {
- "fieldtype": "Button",
- "label": __("Change Code"),
- click: function() {
- var values = d.get_values();
- if(!values)
- return;
- change_item_code_from_template(values["Item Code"], doc);
- d.hide();
- }
+ 'fieldtype': 'Data',
+ 'label': 'Item Code',
+ 'fieldname': 'item_code',
+ reqd: 1
}
- ]
+ ],
+ primary_action: function() {
+ let values = d.get_values();
+
+ if (values) {
+ frappe.call({
+ 'method': 'erpnext.healthcare.doctype.clinical_procedure_template.clinical_procedure_template.change_item_code_from_template',
+ 'args': {item_code: values.item_code, doc: doc},
+ callback: function () {
+ cur_frm.reload_doc();
+ frappe.show_alert({
+ message: 'Item Code renamed successfully',
+ indicator: 'green'
+ });
+ }
+ });
+ }
+ d.hide();
+ },
+ primary_action_label: __('Change Item Code')
});
d.show();
- d.set_values({
- 'Item Code': doc.item_code
- });
-};
-var change_item_code_from_template = function(item_code, doc){
- frappe.call({
- "method": "erpnext.healthcare.doctype.clinical_procedure_template.clinical_procedure_template.change_item_code_from_template",
- "args": {item_code: item_code, doc: doc},
- callback: function () {
- cur_frm.reload_doc();
- frappe.show_alert({
- message: "Item Code renamed successfully",
- indicator: "green"
- });
- }
+ d.set_values({
+ 'item_code': doc.item_code
});
};
frappe.ui.form.on('Clinical Procedure Item', {
- qty: function(frm, cdt, cdn){
- var d = locals[cdt][cdn];
- frappe.model.set_value(cdt, cdn, "transfer_qty", d.qty*d.conversion_factor);
+ qty: function(frm, cdt, cdn) {
+ let d = locals[cdt][cdn];
+ frappe.model.set_value(cdt, cdn, 'transfer_qty', d.qty * d.conversion_factor);
},
+
uom: function(doc, cdt, cdn){
- var d = locals[cdt][cdn];
- if(d.uom && d.item_code){
+ let d = locals[cdt][cdn];
+ if (d.uom && d.item_code) {
return frappe.call({
- method: "erpnext.stock.doctype.stock_entry.stock_entry.get_uom_details",
+ method: 'erpnext.stock.doctype.stock_entry.stock_entry.get_uom_details',
args: {
item_code: d.item_code,
uom: d.uom,
qty: d.qty
},
callback: function(r) {
- if(r.message) {
+ if (r.message) {
frappe.model.set_value(cdt, cdn, r.message);
}
}
});
}
},
+
item_code: function(frm, cdt, cdn) {
- var d = locals[cdt][cdn];
- if(d.item_code) {
+ let d = locals[cdt][cdn];
+ if (d.item_code) {
let args = {
'item_code' : d.item_code,
'transfer_qty' : d.transfer_qty,
- 'company' : frm.doc.company,
- 'quantity' : d.qty
+ 'quantity' : d.qty
};
return frappe.call({
- doc: frm.doc,
- method: "get_item_details",
- args: args,
+ method: 'erpnext.healthcare.doctype.clinical_procedure_template.clinical_procedure_template.get_item_details',
+ args: {args: args},
callback: function(r) {
- if(r.message) {
- var d = locals[cdt][cdn];
- $.each(r.message, function(k, v){
+ if (r.message) {
+ let d = locals[cdt][cdn];
+ $.each(r.message, function(k, v) {
d[k] = v;
});
- refresh_field("items");
+ refresh_field('items');
}
}
});
}
}
});
+
// List Stock items
-cur_frm.set_query("item_code", "items", function() {
+cur_frm.set_query('item_code', 'items', function() {
return {
filters: {
is_stock_item:1
diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json
index 26564a3..9cfd682 100644
--- a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json
+++ b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json
@@ -1,807 +1,236 @@
{
- "allow_copy": 0,
- "allow_events_in_timeline": 0,
- "allow_guest_to_view": 0,
- "allow_import": 1,
- "allow_rename": 1,
- "autoname": "field:template",
- "beta": 1,
- "creation": "2017-10-05 14:59:55.438359",
- "custom": 0,
- "description": "Procedure Template",
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "actions": [],
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "field:template",
+ "beta": 1,
+ "creation": "2017-10-05 14:59:55.438359",
+ "description": "Procedure Template",
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "template",
+ "item",
+ "item_code",
+ "item_group",
+ "description",
+ "column_break_5",
+ "disabled",
+ "is_billable",
+ "rate",
+ "medical_department",
+ "consumables",
+ "consume_stock",
+ "items",
+ "sample_collection",
+ "sample",
+ "sample_uom",
+ "sample_qty",
+ "column_break_21",
+ "sample_details",
+ "change_in_item"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "template",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 1,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Template Name",
- "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,
- "translatable": 0,
+ "fieldname": "template",
+ "fieldtype": "Data",
+ "in_global_search": 1,
+ "in_list_view": 1,
+ "label": "Template Name",
+ "reqd": 1,
"unique": 1
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "item_code",
+ "fieldname": "item_code",
+ "fieldtype": "Data",
+ "label": "Item Code",
+ "options": "Item",
+ "read_only_depends_on": "eval: !doc.__islocal ",
+ "reqd": 1
+ },
+ {
+ "fieldname": "item_group",
"fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Item Code",
- "length": 0,
- "no_copy": 1,
- "options": "Item",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "ignore_user_permissions": 1,
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Item Group",
+ "options": "Item Group",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "item_group",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Item Group",
- "length": 0,
- "no_copy": 0,
- "options": "Item Group",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "medical_department",
+ "fieldtype": "Link",
+ "label": "Medical Department",
+ "options": "Medical Department"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "medical_department",
- "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": "Medical Department",
- "length": 0,
- "no_copy": 0,
- "options": "Medical Department",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_5",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_5",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "is_billable",
+ "fieldtype": "Check",
+ "label": "Is Billable"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "is_billable",
- "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": "Is Billable",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "depends_on": "is_billable",
+ "fieldname": "rate",
+ "fieldtype": "Float",
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Rate",
+ "mandatory_depends_on": "is_billable"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "is_billable",
- "fieldname": "rate",
- "fieldtype": "Float",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Rate",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "description",
+ "fieldtype": "Small Text",
+ "ignore_xss_filter": 1,
+ "label": "Description",
+ "no_copy": 1,
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "description",
- "fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Description",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "consume_stock",
+ "fieldtype": "Check",
+ "label": "Allow Stock Consumption",
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "section_break_9",
- "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,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "consumables",
+ "fieldtype": "Section Break",
+ "label": "Consumables"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "consume_stock",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Allow Stock Consumption",
- "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": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "depends_on": "eval:doc.consume_stock == 1",
+ "fieldname": "items",
+ "fieldtype": "Table",
+ "ignore_user_permissions": 1,
+ "label": "Items",
+ "options": "Clinical Procedure Item"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:doc.consume_stock == 1",
- "fieldname": "consumables",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Consumables",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "collapsible": 1,
+ "fieldname": "sample_collection",
+ "fieldtype": "Section Break",
+ "label": "Sample Collection"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "items",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Items",
- "length": 0,
- "no_copy": 0,
- "options": "Clinical Procedure Item",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "sample",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "label": "Sample",
+ "options": "Lab Test Sample"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 1,
- "columns": 0,
- "depends_on": "",
- "fieldname": "sample_collection",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Sample Collection",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "sample.sample_uom",
+ "fieldname": "sample_uom",
+ "fieldtype": "Data",
+ "label": "Sample UOM",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sample",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Sample",
- "length": 0,
- "no_copy": 0,
- "options": "Lab Test Sample",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "sample_qty",
+ "fieldtype": "Float",
+ "label": "Quantity"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "sample.sample_uom",
- "fieldname": "sample_uom",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "UOM",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_21",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sample_qty",
- "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": "Quantity",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "sample_details",
+ "fieldtype": "Small Text",
+ "ignore_xss_filter": 1,
+ "label": "Collection Details"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_21",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "change_in_item",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "label": "Change In Item",
+ "no_copy": 1,
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sample_details",
- "fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Collection Details",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "disabled",
+ "fieldtype": "Check",
+ "label": "Disabled"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "change_in_item",
- "fieldtype": "Check",
- "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": "Change In Item",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "disabled",
- "fieldtype": "Check",
- "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": "Disabled",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "item",
- "fieldtype": "Link",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Item",
- "length": 0,
- "no_copy": 1,
- "options": "Item",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "fieldname": "item",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Item",
+ "no_copy": 1,
+ "options": "Item",
+ "read_only": 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": 0,
- "max_attachments": 0,
- "modified": "2019-02-12 11:37:18.713344",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Clinical Procedure Template",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "links": [],
+ "modified": "2020-02-28 14:16:13.184981",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Clinical Procedure Template",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "System Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "System Manager",
+ "share": 1,
"write": 1
- },
+ },
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Healthcare Administrator",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Healthcare Administrator",
+ "share": 1,
"write": 1
- },
+ },
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Nursing User",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 0
- },
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Nursing User",
+ "share": 1
+ },
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Physician",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Physician",
+ "share": 1,
"write": 1
}
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "search_fields": "template",
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "template",
- "track_changes": 1,
- "track_seen": 1,
- "track_views": 0
+ ],
+ "restrict_to_domain": "Healthcare",
+ "search_fields": "template",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "template",
+ "track_changes": 1,
+ "track_seen": 1
}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py
index 5a71ca5..3f295af 100644
--- a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py
+++ b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py
@@ -7,126 +7,114 @@
from frappe import _
from frappe.model.document import Document
from frappe.model.rename_doc import rename_doc
-from frappe.utils import nowdate
class ClinicalProcedureTemplate(Document):
- def on_update(self):
- #Item and Price List update --> if (change_in_item)
- if(self.change_in_item and self.is_billable == 1 and self.item):
- updating_item(self)
- if(self.rate != 0.0):
- updating_rate(self)
- elif(self.is_billable == 0 and self.item):
- frappe.db.set_value("Item",self.item,"disabled",1)
-
- frappe.db.set_value(self.doctype,self.name,"change_in_item",0)
- self.reload()
+ def validate(self):
+ self.enable_disable_item()
def after_insert(self):
create_item_from_template(self)
- #Call before delete the template
- def on_trash(self):
- if(self.item):
- try:
- frappe.delete_doc("Item",self.item)
- except Exception:
- frappe.throw(_("""Not permitted. Please disable the Procedure Template"""))
+ def on_update(self):
+ if self.change_in_item:
+ self.update_item_and_item_price()
- def get_item_details(self, args=None):
- item = frappe.db.sql("""select stock_uom, item_name
- from `tabItem`
- where name = %s
- and disabled=0
- and (end_of_life is null or end_of_life='0000-00-00' or end_of_life > %s)""",
- (args.get('item_code'), nowdate()), as_dict = 1)
- if not item:
- frappe.throw(_("Item {0} is not active or end of life has been reached").format(args.get('item_code')))
+ def enable_disable_item(self):
+ if self.is_billable:
+ if self.disabled:
+ frappe.db.set_value('Item', self.item, 'disabled', 1)
+ else:
+ frappe.db.set_value('Item', self.item, 'disabled', 0)
- item = item[0]
+ def update_item_and_item_price(self):
+ if self.is_billable and self.item:
+ item_doc = frappe.get_doc('Item', {'item_code': self.item})
+ item_doc.item_name = self.template
+ item_doc.item_group = self.item_group
+ item_doc.description = self.description
+ item_doc.disabled = 0
+ item_doc.save(ignore_permissions=True)
- ret = {
- 'uom' : item.stock_uom,
- 'stock_uom' : item.stock_uom,
- 'item_name' : item.item_name,
- 'quantity' : 0,
- 'transfer_qty' : 0,
- 'conversion_factor' : 1
- }
- return ret
+ if self.rate:
+ item_price = frappe.get_doc('Item Price', {'item_code': self.item})
+ item_price.item_name = self.template
+ item_price.price_list_rate = self.rate
+ item_price.save()
-def updating_item(self):
- frappe.db.sql("""update `tabItem` set item_name=%s, item_group=%s, disabled=0,
- description=%s, modified=NOW() where item_code=%s""",
- (self.template, self.item_group , self.description, self.item))
-def updating_rate(self):
- frappe.db.sql("""update `tabItem Price` set item_name=%s, price_list_rate=%s, modified=NOW() where
- item_code=%s""",(self.template, self.rate, self.item))
+ elif not self.is_billable and self.item:
+ frappe.db.set_value('Item', self.item, 'disabled', 1)
+
+ self.db_set('change_in_item', 0)
+
+
+@frappe.whitelist()
+def get_item_details(args=None):
+ if not isinstance(args, dict):
+ args = json.loads(args)
+
+ item = frappe.db.get_all('Item',
+ filters={
+ 'disabled': 0,
+ 'name': args.get('item_code')
+ },
+ fields=['stock_uom', 'item_name']
+ )
+
+ if not item:
+ frappe.throw(_('Item {0} is not active').format(args.get('item_code')))
+
+ item = item[0]
+ ret = {
+ 'uom': item.stock_uom,
+ 'stock_uom': item.stock_uom,
+ 'item_name': item.item_name,
+ 'qty': 1,
+ 'transfer_qty': 0,
+ 'conversion_factor': 1
+ }
+ return ret
def create_item_from_template(doc):
- disabled = 1
-
- if(doc.is_billable == 1):
+ disabled = doc.disabled
+ if doc.is_billable and not doc.disabled:
disabled = 0
- #insert item
- item = frappe.get_doc({
- "doctype": "Item",
- "item_code": doc.template,
- "item_name":doc.template,
- "item_group": doc.item_group,
- "description":doc.description,
- "is_sales_item": 1,
- "is_service_item": 1,
- "is_purchase_item": 0,
- "is_stock_item": 0,
- "show_in_website": 0,
- "is_pro_applicable": 0,
- "disabled": disabled,
- "stock_uom": "Unit"
- }).insert(ignore_permissions=True)
+ item = frappe.get_doc({
+ 'doctype': 'Item',
+ 'item_code': doc.template,
+ 'item_name':doc.template,
+ 'item_group': doc.item_group,
+ 'description':doc.description,
+ 'is_sales_item': 1,
+ 'is_service_item': 1,
+ 'is_purchase_item': 0,
+ 'is_stock_item': 0,
+ 'show_in_website': 0,
+ 'is_pro_applicable': 0,
+ 'disabled': disabled,
+ 'stock_uom': 'Unit'
+ }).insert(ignore_permissions=True, ignore_mandatory=True)
- #insert item price
- #get item price list to insert item price
- if(doc.rate != 0.0):
- price_list_name = frappe.db.get_value("Price List", {"selling": 1})
- if(doc.rate):
- make_item_price(item.name, price_list_name, doc.rate)
- else:
- make_item_price(item.name, price_list_name, 0.0)
- #Set item to the template
- frappe.db.set_value("Clinical Procedure Template", doc.name, "item", item.name)
+ make_item_price(item.name, doc.rate)
+ doc.db_set('item', item.name)
- doc.reload() #refresh the doc after insert.
-
-def make_item_price(item, price_list_name, item_price):
+def make_item_price(item, item_price):
+ price_list_name = frappe.db.get_value('Price List', {'selling': 1})
frappe.get_doc({
- "doctype": "Item Price",
- "price_list": price_list_name,
- "item_code": item,
- "price_list_rate": item_price
- }).insert(ignore_permissions=True)
+ 'doctype': 'Item Price',
+ 'price_list': price_list_name,
+ 'item_code': item,
+ 'price_list_rate': item_price
+ }).insert(ignore_permissions=True, ignore_mandatory=True)
@frappe.whitelist()
def change_item_code_from_template(item_code, doc):
- args = json.loads(doc)
- doc = frappe._dict(args)
+ doc = frappe._dict(json.loads(doc))
- if(frappe.db.exists({
- "doctype": "Item",
- "item_code": item_code})):
- frappe.throw(_("Code {0} already exist").format(item_code))
+ if frappe.db.exists('Item', {'item_code': item_code}):
+ frappe.throw(_('Item with Item Code {0} already exists').format(item_code))
else:
- rename_doc("Item", doc.item_code, item_code, ignore_permissions=True)
- frappe.db.set_value("Clinical Procedure Template", doc.name, "item_code", item_code)
+ rename_doc('Item', doc.item_code, item_code, ignore_permissions=True)
+ frappe.db.set_value('Clinical Procedure Template', doc.name, 'item_code', item_code)
return
-@frappe.whitelist()
-def disable_enable_template(status, name, item_code):
- frappe.db.set_value("Clinical Procedure Template", name, "disabled", status)
- if (frappe.db.exists({ #set Item's disabled field to status
- "doctype": "Item",
- "item_code": item_code})):
- frappe.db.set_value("Item", item_code, "disabled", status)
-
- return
diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template_dashboard.py b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template_dashboard.py
new file mode 100644
index 0000000..9aab521
--- /dev/null
+++ b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template_dashboard.py
@@ -0,0 +1,13 @@
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+ return {
+ 'fieldname': 'procedure_template',
+ 'transactions': [
+ {
+ 'label': _('Consultations'),
+ 'items': ['Clinical Procedure']
+ }
+ ]
+ }
diff --git a/erpnext/healthcare/doctype/codification_table/codification_table.json b/erpnext/healthcare/doctype/codification_table/codification_table.json
index e65ae77..9a917b4 100644
--- a/erpnext/healthcare/doctype/codification_table/codification_table.json
+++ b/erpnext/healthcare/doctype/codification_table/codification_table.json
@@ -1,140 +1,56 @@
{
- "allow_copy": 1,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 1,
- "creation": "2017-06-22 13:09:23.159579",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "actions": [],
+ "allow_copy": 1,
+ "beta": 1,
+ "creation": "2017-06-22 13:09:23.159579",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "medical_code",
+ "code",
+ "description"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "medical_code",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Medical Code",
- "length": 0,
- "no_copy": 0,
- "options": "Medical Code",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "medical_code",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "in_list_view": 1,
+ "label": "Medical Code",
+ "options": "Medical Code",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fetch_from": "medical_code.code",
- "fieldname": "code",
- "fieldtype": "Read Only",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Code",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "code",
+ "fieldtype": "Data",
+ "ignore_xss_filter": 1,
+ "in_list_view": 1,
+ "label": "Code",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fetch_from": "medical_code.description",
- "fieldname": "description",
- "fieldtype": "Read Only",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Description",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "fieldname": "description",
+ "fieldtype": "Small Text",
+ "ignore_xss_filter": 1,
+ "in_list_view": 1,
+ "label": "Description",
+ "read_only": 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": "2018-05-16 22:43:27.047479",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Codification Table",
- "name_case": "",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1,
- "track_seen": 0
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-02-26 13:17:49.016293",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Codification Table",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "restrict_to_domain": "Healthcare",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/drug_prescription/drug_prescription.json b/erpnext/healthcare/doctype/drug_prescription/drug_prescription.json
index 5647d3c..5e4d59c 100644
--- a/erpnext/healthcare/doctype/drug_prescription/drug_prescription.json
+++ b/erpnext/healthcare/doctype/drug_prescription/drug_prescription.json
@@ -1,381 +1,116 @@
{
- "allow_copy": 1,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 1,
- "creation": "2016-09-16 16:41:45.533374",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Document",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "actions": [],
+ "allow_copy": 1,
+ "beta": 1,
+ "creation": "2016-09-16 16:41:45.533374",
+ "doctype": "DocType",
+ "document_type": "Document",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "drug_code",
+ "drug_name",
+ "dosage",
+ "period",
+ "dosage_form",
+ "column_break_7",
+ "comment",
+ "usage_interval",
+ "interval",
+ "interval_uom",
+ "update_schedule"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "drug_code",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Drug Code",
- "length": 0,
- "no_copy": 0,
- "options": "Item",
- "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
- },
+ "fieldname": "drug_code",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "in_list_view": 1,
+ "label": "Drug",
+ "options": "Item",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "drug_name",
- "fieldtype": "Data",
- "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": "Description/Strength",
- "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
- },
+ "fetch_from": "drug_code.item_name",
+ "fieldname": "drug_name",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Drug Name / Description"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "dosage",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Dosage",
- "length": 0,
- "no_copy": 0,
- "options": "Prescription Dosage",
- "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
- },
+ "fieldname": "dosage",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "in_list_view": 1,
+ "label": "Dosage",
+ "options": "Prescription Dosage"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "period",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Period",
- "length": 0,
- "no_copy": 0,
- "options": "Prescription Duration",
- "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
- },
+ "fieldname": "period",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "in_list_view": 1,
+ "label": "Period",
+ "options": "Prescription Duration"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "dosage_form",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Dosage Form",
- "length": 0,
- "no_copy": 0,
- "options": "Dosage Form",
- "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
- },
+ "fieldname": "dosage_form",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "label": "Dosage Form",
+ "options": "Dosage Form"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_7",
- "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
- },
+ "fieldname": "column_break_7",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "comment",
- "fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Comment",
- "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
- },
+ "fieldname": "comment",
+ "fieldtype": "Small Text",
+ "ignore_xss_filter": 1,
+ "in_list_view": 1,
+ "label": "Comment"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "use_interval",
- "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": "Dosage by time interval",
- "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
- },
+ "depends_on": "use_interval",
+ "fieldname": "interval",
+ "fieldtype": "Int",
+ "in_list_view": 1,
+ "label": "Interval"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "use_interval",
- "fieldname": "interval",
- "fieldtype": "Int",
- "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": "Interval",
- "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
- },
+ "default": "1",
+ "fieldname": "update_schedule",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "label": "Update Schedule",
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "use_interval",
- "fieldname": "in_every",
- "fieldtype": "Select",
- "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": "Interval UOM",
- "length": 0,
- "no_copy": 0,
- "options": "\nHour\nDay",
- "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
- },
+ "depends_on": "use_interval",
+ "fieldname": "interval_uom",
+ "fieldtype": "Select",
+ "in_list_view": 1,
+ "label": "Interval UOM",
+ "options": "\nHour\nDay"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "1",
- "fieldname": "update_schedule",
- "fieldtype": "Check",
- "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": "Update Schedule",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
+ "default": "0",
+ "fieldname": "usage_interval",
+ "fieldtype": "Check",
+ "label": "Dosage by Time Interval"
}
- ],
- "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-10-04 17:09:54.998517",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Drug Prescription",
- "name_case": "",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 0,
- "track_seen": 0
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-02-26 17:02:42.741338",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Drug Prescription",
+ "owner": "Administrator",
+ "permissions": [],
+ "restrict_to_domain": "Healthcare",
+ "sort_field": "modified",
+ "sort_order": "DESC"
}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/drug_prescription/drug_prescription.py b/erpnext/healthcare/doctype/drug_prescription/drug_prescription.py
index 0d99198..68a2dc5 100755
--- a/erpnext/healthcare/doctype/drug_prescription/drug_prescription.py
+++ b/erpnext/healthcare/doctype/drug_prescription/drug_prescription.py
@@ -12,21 +12,21 @@
dosage = None
period = None
- if(self.dosage):
- dosage = frappe.get_doc("Prescription Dosage",self.dosage)
+ if self.dosage:
+ dosage = frappe.get_doc('Prescription Dosage', self.dosage)
for item in dosage.dosage_strength:
quantity += item.strength
- if(self.period and self.interval):
- period = frappe.get_doc("Prescription Duration",self.period)
- if(self.interval < period.get_days()):
- quantity = quantity*(period.get_days()/self.interval)
+ if self.period and self.interval:
+ period = frappe.get_doc('Prescription Duration', self.period)
+ if self.interval < period.get_days():
+ quantity = quantity * (period.get_days()/self.interval)
- elif(self.interval and self.in_every and self.period):
- period = frappe.get_doc("Prescription Duration",self.period)
- interval_in = self.in_every
- if(interval_in == 'Day' and (self.interval < period.get_days())):
+ elif self.interval and self.interval_uom and self.period:
+ period = frappe.get_doc('Prescription Duration', self.period)
+ interval_in = self.interval_uom
+ if interval_in == 'Day' and self.interval < period.get_days():
quantity = period.get_days()/self.interval
- elif(interval_in == 'Hour' and (self.interval < period.get_hours())):
+ elif interval_in == 'Hour' and self.interval < period.get_hours():
quantity = period.get_hours()/self.interval
if quantity > 0:
return quantity
diff --git a/erpnext/healthcare/doctype/fee_validity/fee_validity.json b/erpnext/healthcare/doctype/fee_validity/fee_validity.json
index 802f04a..b001bf0 100644
--- a/erpnext/healthcare/doctype/fee_validity/fee_validity.json
+++ b/erpnext/healthcare/doctype/fee_validity/fee_validity.json
@@ -1,259 +1,134 @@
{
- "allow_copy": 1,
- "allow_guest_to_view": 0,
- "allow_import": 1,
- "allow_rename": 0,
- "beta": 1,
- "creation": "2017-01-05 10:56:29.564806",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "actions": [],
+ "allow_copy": 1,
+ "allow_import": 1,
+ "beta": 1,
+ "creation": "2017-01-05 10:56:29.564806",
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "practitioner",
+ "patient",
+ "column_break_3",
+ "status",
+ "section_break_5",
+ "section_break_3",
+ "max_visits",
+ "visited",
+ "ref_appointments",
+ "column_break_6",
+ "start_date",
+ "valid_till"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "practitioner",
- "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": "Healthcare Practitioner",
- "length": 0,
- "no_copy": 0,
- "options": "Healthcare Practitioner",
- "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": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "practitioner",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Healthcare Practitioner",
+ "options": "Healthcare Practitioner",
+ "read_only": 1,
+ "reqd": 1,
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "patient",
- "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": "Patient",
- "length": 0,
- "no_copy": 0,
- "options": "Patient",
- "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": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "patient",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Patient",
+ "options": "Patient",
+ "read_only": 1,
+ "reqd": 1,
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "max_visit",
- "fieldtype": "Int",
- "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 number of visit",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "visited",
+ "fieldtype": "Int",
+ "label": "Visited yet",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "visited",
- "fieldtype": "Int",
- "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": "Visited yet",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "valid_till",
+ "fieldtype": "Date",
+ "label": "Valid till",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "valid_till",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Valid till",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "section_break_3",
+ "fieldtype": "Section Break",
+ "label": "Validity",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "ref_invoice",
- "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": "Reference Inv",
- "length": 0,
- "no_copy": 0,
- "options": "Sales Invoice",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "fieldname": "column_break_6",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "max_visits",
+ "fieldtype": "Int",
+ "label": "Max number of visit",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_3",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Status",
+ "options": "Completed\nPending",
+ "read_only": 1
+ },
+ {
+ "fetch_from": "ref_appointment.appointment_date",
+ "fieldname": "start_date",
+ "fieldtype": "Date",
+ "label": "Start Date",
+ "read_only": 1
+ },
+ {
+ "fieldname": "ref_appointments",
+ "fieldtype": "Table MultiSelect",
+ "label": "Reference Appointments",
+ "options": "Fee Validity Reference",
+ "read_only": 1
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "section_break_5",
+ "fieldtype": "Section Break"
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-07-16 12:43:45.635230",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Fee Validity",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "in_create": 1,
+ "links": [],
+ "modified": "2020-03-17 20:25:06.487418",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Fee Validity",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Healthcare Administrator",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Healthcare Administrator",
+ "share": 1,
"write": 1
}
- ],
- "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "search_fields": "practitioner, patient",
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "practitioner",
- "track_changes": 0,
- "track_seen": 0
+ ],
+ "quick_entry": 1,
+ "restrict_to_domain": "Healthcare",
+ "search_fields": "practitioner, patient",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "practitioner"
}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/fee_validity/fee_validity.py b/erpnext/healthcare/doctype/fee_validity/fee_validity.py
index 9028545..058bc97 100644
--- a/erpnext/healthcare/doctype/fee_validity/fee_validity.py
+++ b/erpnext/healthcare/doctype/fee_validity/fee_validity.py
@@ -9,28 +9,55 @@
import datetime
class FeeValidity(Document):
- pass
+ def validate(self):
+ self.update_status()
+ self.set_start_date()
-def update_fee_validity(fee_validity, date, ref_invoice=None):
- max_visit = frappe.db.get_value("Healthcare Settings", None, "max_visit")
- valid_days = frappe.db.get_value("Healthcare Settings", None, "valid_days")
- if not valid_days:
- valid_days = 1
- if not max_visit:
- max_visit = 1
- date = getdate(date)
- valid_till = date + datetime.timedelta(days=int(valid_days))
- fee_validity.max_visit = max_visit
+ def update_status(self):
+ if self.visited >= self.max_visits:
+ self.status = 'Completed'
+ else:
+ self.status = 'Pending'
+
+ def set_start_date(self):
+ self.start_date = getdate()
+ for appointment in self.ref_appointments:
+ appointment_date = frappe.db.get_value('Patient Appointment', appointment.appointment, 'appointment_date')
+ if getdate(appointment_date) < self.start_date:
+ self.start_date = getdate(appointment_date)
+
+
+def create_fee_validity(appointment):
+ if not check_is_new_patient(appointment):
+ return
+
+ fee_validity = frappe.new_doc('Fee Validity')
+ fee_validity.practitioner = appointment.practitioner
+ fee_validity.patient = appointment.patient
+ fee_validity.max_visits = frappe.db.get_single_value('Healthcare Settings', 'max_visits') or 1
+ valid_days = frappe.db.get_single_value('Healthcare Settings', 'valid_days') or 1
fee_validity.visited = 1
- fee_validity.valid_till = valid_till
- fee_validity.ref_invoice = ref_invoice
+ fee_validity.valid_till = getdate(appointment.appointment_date) + datetime.timedelta(days=int(valid_days))
+ fee_validity.append('ref_appointments', {
+ 'appointment': appointment.name
+ })
fee_validity.save(ignore_permissions=True)
return fee_validity
+def check_is_new_patient(appointment):
+ validity_exists = frappe.db.exists('Fee Validity', {
+ 'practitioner': appointment.practitioner,
+ 'patient': appointment.patient
+ })
+ if validity_exists:
+ return False
-def create_fee_validity(practitioner, patient, date, ref_invoice=None):
- fee_validity = frappe.new_doc("Fee Validity")
- fee_validity.practitioner = practitioner
- fee_validity.patient = patient
- fee_validity = update_fee_validity(fee_validity, date, ref_invoice)
- return fee_validity
+ appointment_exists = frappe.db.get_all('Patient Appointment', {
+ 'name': ('!=', appointment.name),
+ 'status': ('!=', 'Cancelled'),
+ 'patient': appointment.patient,
+ 'practitioner': appointment.practitioner
+ })
+ if len(appointment_exists) and appointment_exists[0]:
+ return False
+ return True
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/fee_validity/test_fee_validity.py b/erpnext/healthcare/doctype/fee_validity/test_fee_validity.py
index 26b1450..cdf692e 100644
--- a/erpnext/healthcare/doctype/fee_validity/test_fee_validity.py
+++ b/erpnext/healthcare/doctype/fee_validity/test_fee_validity.py
@@ -5,100 +5,44 @@
import frappe
import unittest
-from frappe.utils.make_random import get_random
-from frappe.utils import nowdate, add_days, getdate
+from frappe.utils import nowdate, add_days
+from erpnext.healthcare.doctype.patient_appointment.test_patient_appointment import create_healthcare_docs, create_appointment, create_healthcare_service_items
test_dependencies = ["Company"]
class TestFeeValidity(unittest.TestCase):
- def test_fee_validity(self):
+ def setUp(self):
frappe.db.sql("""delete from `tabPatient Appointment`""")
frappe.db.sql("""delete from `tabFee Validity`""")
- patient = get_random("Patient")
- practitioner = get_random("Healthcare Practitioner")
- department = get_random("Medical Department")
+ frappe.db.sql("""delete from `tabPatient`""")
- if not patient:
- patient = frappe.new_doc("Patient")
- patient.patient_name = "_Test Patient"
- patient.sex = "Male"
- patient.save(ignore_permissions=True)
- patient = patient.name
+ def test_fee_validity(self):
+ item = create_healthcare_service_items()
+ healthcare_settings = frappe.get_single("Healthcare Settings")
+ healthcare_settings.enable_free_follow_ups = 1
+ healthcare_settings.max_visits = 2
+ healthcare_settings.valid_days = 7
+ healthcare_settings.automate_appointment_invoicing = 1
+ healthcare_settings.op_consulting_charge_item = item
+ healthcare_settings.save(ignore_permissions=True)
+ patient, medical_department, practitioner = create_healthcare_docs()
- if not department:
- medical_department = frappe.new_doc("Medical Department")
- medical_department.department = "_Test Medical Department"
- medical_department.save(ignore_permissions=True)
- department = medical_department.name
-
- if not practitioner:
- practitioner = frappe.new_doc("Healthcare Practitioner")
- practitioner.first_name = "_Test Healthcare Practitioner"
- practitioner.department = department
- practitioner.save(ignore_permissions=True)
- practitioner = practitioner.name
-
-
-
- frappe.db.set_value("Healthcare Settings", None, "max_visit", 2)
- frappe.db.set_value("Healthcare Settings", None, "valid_days", 7)
-
- appointment = create_appointment(patient, practitioner, nowdate(), department)
+ # appointment should not be invoiced. Check Fee Validity created for new patient
+ appointment = create_appointment(patient, practitioner, nowdate())
invoiced = frappe.db.get_value("Patient Appointment", appointment.name, "invoiced")
self.assertEqual(invoiced, 0)
- invoice_appointment(appointment)
-
- appointment = create_appointment(patient, practitioner, add_days(nowdate(), 4), department)
- invoiced = frappe.db.get_value("Patient Appointment", appointment.name, "invoiced")
- self.assertTrue(invoiced)
-
- appointment = create_appointment(patient, practitioner, add_days(nowdate(), 5), department)
+ # appointment should not be invoiced as it is within fee validity
+ appointment = create_appointment(patient, practitioner, add_days(nowdate(), 4))
invoiced = frappe.db.get_value("Patient Appointment", appointment.name, "invoiced")
self.assertEqual(invoiced, 0)
- appointment = create_appointment(patient, practitioner, add_days(nowdate(), 10), department)
+ # appointment should be invoiced as it is within fee validity but the max_visits are exceeded
+ appointment = create_appointment(patient, practitioner, add_days(nowdate(), 5), invoice=1)
invoiced = frappe.db.get_value("Patient Appointment", appointment.name, "invoiced")
- self.assertEqual(invoiced, 0)
+ self.assertEqual(invoiced, 1)
-def create_appointment(patient, practitioner, appointment_date, department):
- appointment = frappe.new_doc("Patient Appointment")
- appointment.patient = patient
- appointment.practitioner = practitioner
- appointment.department = department
- appointment.appointment_date = appointment_date
- appointment.company = "_Test Company"
- appointment.duration = 15
- appointment.save(ignore_permissions=True)
- return appointment
-
-def invoice_appointment(appointment_doc):
- if not appointment_doc.name:
- return False
- sales_invoice = frappe.new_doc("Sales Invoice")
- sales_invoice.customer = frappe.get_value("Patient", appointment_doc.patient, "customer")
- sales_invoice.due_date = getdate()
- sales_invoice.is_pos = 0
- sales_invoice.company = appointment_doc.company
- sales_invoice.debit_to = "_Test Receivable - _TC"
-
- create_invoice_items(appointment_doc, sales_invoice)
-
- sales_invoice.save(ignore_permissions=True)
- sales_invoice.submit()
-
-def create_invoice_items(appointment, invoice):
- item_line = invoice.append("items")
- item_line.item_name = "Consulting Charges"
- item_line.description = "Consulting Charges: " + appointment.practitioner
- item_line.uom = "Nos"
- item_line.conversion_factor = 1
- item_line.income_account = "_Test Account Cost for Goods Sold - _TC"
- item_line.cost_center = "_Test Cost Center - _TC"
- item_line.rate = 250
- item_line.amount = 250
- item_line.qty = 1
- item_line.reference_dt = "Patient Appointment"
- item_line.reference_dn = appointment.name
-
- return invoice
+ # appointment should be invoiced as it is not within fee validity and the max_visits are exceeded
+ appointment = create_appointment(patient, practitioner, add_days(nowdate(), 10), invoice=1)
+ invoiced = frappe.db.get_value("Patient Appointment", appointment.name, "invoiced")
+ self.assertEqual(invoiced, 1)
\ No newline at end of file
diff --git a/erpnext/healthcare/page/appointment_analytic/__init__.py b/erpnext/healthcare/doctype/fee_validity_reference/__init__.py
similarity index 100%
rename from erpnext/healthcare/page/appointment_analytic/__init__.py
rename to erpnext/healthcare/doctype/fee_validity_reference/__init__.py
diff --git a/erpnext/healthcare/doctype/fee_validity_reference/fee_validity_reference.json b/erpnext/healthcare/doctype/fee_validity_reference/fee_validity_reference.json
new file mode 100644
index 0000000..40f128e
--- /dev/null
+++ b/erpnext/healthcare/doctype/fee_validity_reference/fee_validity_reference.json
@@ -0,0 +1,32 @@
+{
+ "actions": [],
+ "creation": "2020-03-13 16:08:42.859996",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "appointment"
+ ],
+ "fields": [
+ {
+ "fieldname": "appointment",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Patient Appointment",
+ "options": "Patient Appointment",
+ "reqd": 1
+ }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-03-15 00:27:02.076470",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Fee Validity Reference",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/fee_validity_reference/fee_validity_reference.py b/erpnext/healthcare/doctype/fee_validity_reference/fee_validity_reference.py
new file mode 100644
index 0000000..c819280
--- /dev/null
+++ b/erpnext/healthcare/doctype/fee_validity_reference/fee_validity_reference.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class FeeValidityReference(Document):
+ pass
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.js b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.js
index efca484..4ab3b6e 100644
--- a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.js
+++ b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.js
@@ -4,7 +4,7 @@
frappe.ui.form.on('Healthcare Practitioner', {
setup: function(frm) {
frm.set_query('account', 'accounts', function(doc, cdt, cdn) {
- var d = locals[cdt][cdn];
+ let d = locals[cdt][cdn];
return {
filters: {
'root_type': 'Income',
@@ -16,23 +16,28 @@
},
refresh: function(frm) {
frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Healthcare Practitioner'};
- if(!frm.is_new()) {
+
+ if (!frm.is_new()) {
frappe.contacts.render_address_and_contact(frm);
+ } else {
+ frappe.contacts.clear_address_and_contact(frm);
}
- frm.set_query("service_unit", "practitioner_schedules", function(){
+
+ frm.set_query('service_unit', 'practitioner_schedules', function(){
return {
filters: {
- "is_group": false,
- "allow_appointments": true
+ 'is_group': false,
+ 'allow_appointments': true
}
};
});
+
set_query_service_item(frm, 'inpatient_visit_charge_item');
set_query_service_item(frm, 'op_consulting_charge_item');
}
});
-var set_query_service_item = function(frm, service_item_field) {
+let set_query_service_item = function(frm, service_item_field) {
frm.set_query(service_item_field, function() {
return {
filters: {
@@ -43,62 +48,62 @@
});
};
-frappe.ui.form.on("Healthcare Practitioner", "user_id",function(frm) {
- if(frm.doc.user_id){
+frappe.ui.form.on('Healthcare Practitioner', 'user_id',function(frm) {
+ if (frm.doc.user_id) {
frappe.call({
- "method": "frappe.client.get",
+ 'method': 'frappe.client.get',
args: {
- doctype: "User",
+ doctype: 'User',
name: frm.doc.user_id
},
callback: function (data) {
frappe.model.get_value('Employee', {'user_id': frm.doc.user_id}, 'name',
function(data) {
- if(data){
- if(!frm.doc.employee || frm.doc.employee != data.name)
- frappe.model.set_value(frm.doctype,frm.docname, "employee", data.name);
- }else{
- frappe.model.set_value(frm.doctype,frm.docname, "employee", "");
+ if (data) {
+ if (!frm.doc.employee || frm.doc.employee != data.name)
+ frappe.model.set_value(frm.doctype, frm.docname, 'employee', data.name);
+ } else {
+ frappe.model.set_value(frm.doctype, frm.docname, 'employee', '');
}
}
);
- if(!frm.doc.first_name || frm.doc.first_name != data.message.first_name)
- frappe.model.set_value(frm.doctype,frm.docname, "first_name", data.message.first_name);
- if(!frm.doc.middle_name || frm.doc.middle_name != data.message.middle_name)
- frappe.model.set_value(frm.doctype,frm.docname, "middle_name", data.message.middle_name);
- if(!frm.doc.last_name || frm.doc.last_name != data.message.last_name)
- frappe.model.set_value(frm.doctype,frm.docname, "last_name", data.message.last_name);
- if(!frm.doc.mobile_phone || frm.doc.mobile_phone != data.message.mobile_no)
- frappe.model.set_value(frm.doctype,frm.docname, "mobile_phone", data.message.mobile_no);
+ if (!frm.doc.first_name || frm.doc.first_name != data.message.first_name)
+ frappe.model.set_value(frm.doctype,frm.docname, 'first_name', data.message.first_name);
+ if (!frm.doc.middle_name || frm.doc.middle_name != data.message.middle_name)
+ frappe.model.set_value(frm.doctype,frm.docname, 'middle_name', data.message.middle_name);
+ if (!frm.doc.last_name || frm.doc.last_name != data.message.last_name)
+ frappe.model.set_value(frm.doctype,frm.docname, 'last_name', data.message.last_name);
+ if (!frm.doc.mobile_phone || frm.doc.mobile_phone != data.message.mobile_no)
+ frappe.model.set_value(frm.doctype,frm.docname, 'mobile_phone', data.message.mobile_no);
}
});
}
});
-frappe.ui.form.on("Healthcare Practitioner", "employee", function(frm) {
- if(frm.doc.employee){
+frappe.ui.form.on('Healthcare Practitioner', 'employee', function(frm) {
+ if (frm.doc.employee){
frappe.call({
- "method": "frappe.client.get",
+ 'method': 'frappe.client.get',
args: {
- doctype: "Employee",
+ doctype: 'Employee',
name: frm.doc.employee
},
callback: function (data) {
- if(!frm.doc.user_id || frm.doc.user_id != data.message.user_id)
- frm.set_value("user_id", data.message.user_id);
- if(!frm.doc.designation || frm.doc.designation != data.message.designation)
- frappe.model.set_value(frm.doctype,frm.docname, "designation", data.message.designation);
- if(!frm.doc.first_name || !frm.doc.user_id){
- frappe.model.set_value(frm.doctype,frm.docname, "first_name", data.message.employee_name);
- frappe.model.set_value(frm.doctype,frm.docname, "middle_name", "");
- frappe.model.set_value(frm.doctype,frm.docname, "last_name", "");
+ if (!frm.doc.user_id || frm.doc.user_id != data.message.user_id)
+ frm.set_value('user_id', data.message.user_id);
+ if (!frm.doc.designation || frm.doc.designation != data.message.designation)
+ frappe.model.set_value(frm.doctype,frm.docname, 'designation', data.message.designation);
+ if (!frm.doc.first_name || !frm.doc.user_id){
+ frappe.model.set_value(frm.doctype,frm.docname, 'first_name', data.message.first_name);
+ frappe.model.set_value(frm.doctype,frm.docname, 'middle_name', '');
+ frappe.model.set_value(frm.doctype,frm.docname, 'last_name', data.message.last_name);
}
- if(!frm.doc.mobile_phone || !frm.doc.user_id)
- frappe.model.set_value(frm.doctype,frm.docname, "mobile_phone", data.message.cell_number);
- if(!frm.doc.address || frm.doc.address != data.message.current_address)
- frappe.model.set_value(frm.doctype,frm.docname, "address", data.message.current_address);
+ if (!frm.doc.mobile_phone || !frm.doc.user_id)
+ frappe.model.set_value(frm.doctype,frm.docname, 'mobile_phone', data.message.cell_number);
+ if (!frm.doc.address || frm.doc.address != data.message.current_address)
+ frappe.model.set_value(frm.doctype,frm.docname, 'address', data.message.current_address);
}
});
}
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.json b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.json
index 4a848a0..fd5b6e1 100644
--- a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.json
+++ b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.json
@@ -1,1041 +1,327 @@
{
+ "actions": [],
"allow_copy": 1,
- "allow_events_in_timeline": 0,
- "allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
- "autoname": "",
+ "autoname": "naming_series:",
"beta": 1,
"creation": "2016-02-23 11:20:53.565119",
- "custom": 0,
- "docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
- "editable_grid": 0,
+ "engine": "InnoDB",
+ "field_order": [
+ "basic_details_section",
+ "naming_series",
+ "first_name",
+ "middle_name",
+ "last_name",
+ "practitioner_name",
+ "gender",
+ "image",
+ "column_break_7",
+ "status",
+ "mobile_phone",
+ "residence_phone",
+ "office_phone",
+ "employee_and_user_details_section",
+ "employee",
+ "department",
+ "designation",
+ "column_break_17",
+ "user_id",
+ "hospital",
+ "appointments",
+ "practitioner_schedules",
+ "charges",
+ "op_consulting_charge_item",
+ "op_consulting_charge",
+ "column_break_18",
+ "inpatient_visit_charge_item",
+ "inpatient_visit_charge",
+ "account_details",
+ "default_currency",
+ "accounts",
+ "address_and_contacts_section",
+ "address_html",
+ "column_break_19",
+ "contact_html"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "first_name",
"fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 1,
"label": "First Name",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "reqd": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "middle_name",
"fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Middle Name (Optional)",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Middle Name (Optional)"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "last_name",
"fieldtype": "Data",
- "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": "Last Name",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Last Name"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "image",
"fieldtype": "Attach Image",
"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": "Image",
- "length": 0,
"no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "print_hide": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "employee",
"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": "Employee",
- "length": 0,
- "no_copy": 0,
- "options": "Employee",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "options": "Employee"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "user_id",
"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": "User",
- "length": 0,
- "no_copy": 0,
"options": "User",
- "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": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "search_index": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
+ "fetch_from": "employee",
"fieldname": "designation",
"fieldtype": "Link",
- "hidden": 0,
"ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Designation",
- "length": 0,
- "no_copy": 0,
"options": "Designation",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "read_only": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "department",
"fieldtype": "Link",
- "hidden": 0,
"ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
"in_standard_filter": 1,
- "label": "Department",
- "length": 0,
- "no_copy": 0,
- "options": "Medical Department",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Medical Department",
+ "options": "Medical Department"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "column_break_7",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "fieldtype": "Column Break"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "hospital",
"fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Hospital",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Hospital"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "mobile_phone",
"fieldtype": "Data",
- "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": "Mobile",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Mobile"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "residence_phone",
"fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Phone (R)",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Phone (R)"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "office_phone",
"fieldtype": "Data",
- "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": "Phone (Office)",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Phone (Office)"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "1",
- "fieldname": "active",
- "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": "Active",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
+ "collapsible": 1,
"fieldname": "appointments",
"fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Appointments",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Appointments"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "practitioner_schedules",
"fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Practitioner Schedules",
- "length": 0,
- "no_copy": 0,
- "options": "Practitioner Service Unit Schedule",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "options": "Practitioner Service Unit Schedule"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
+ "collapsible": 1,
"fieldname": "charges",
"fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Charges",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Charges"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "op_consulting_charge_item",
"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": "Out Patient Consulting Charge Item",
- "length": 0,
- "no_copy": 0,
- "options": "Item",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "options": "Item"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "op_consulting_charge",
"fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "OP Consulting Charge",
- "length": 0,
- "no_copy": 0,
- "options": "Currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Out Patient Consulting Charge",
+ "options": "Currency"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "column_break_18",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "fieldtype": "Column Break"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "inpatient_visit_charge_item",
"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": "Inpatient Visit Charge Item",
- "length": 0,
- "no_copy": 0,
- "options": "Item",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "options": "Item"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "inpatient_visit_charge",
"fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Inpatient Visit Charge",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Inpatient Visit Charge"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "contacts_and_address",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Contacts and Address",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
+ "depends_on": "eval: !doc.__islocal",
"fieldname": "address_html",
"fieldtype": "HTML",
- "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": "Address HTML",
- "length": 0,
"no_copy": 1,
- "permlevel": 0,
- "precision": "",
"print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "report_hide": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "column_break_19",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "fieldtype": "Column Break"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
+ "depends_on": "eval: !doc.__islocal",
"fieldname": "contact_html",
"fieldtype": "HTML",
- "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": "Contact HTML",
- "length": 0,
"no_copy": 1,
- "permlevel": 0,
- "precision": "",
"print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "report_hide": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
+ "collapsible": 1,
"fieldname": "account_details",
"fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Account Details",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Account Details"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "accounts",
"fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Income Account",
- "length": 0,
- "no_copy": 0,
- "options": "Party Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "options": "Party Account"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "default_currency",
"fieldtype": "Link",
"hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Default Currency",
- "length": 0,
"no_copy": 1,
"options": "Currency",
- "permlevel": 0,
- "precision": "",
"print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
+ "report_hide": 1
+ },
+ {
+ "bold": 1,
+ "fieldname": "practitioner_name",
+ "fieldtype": "Data",
+ "in_global_search": 1,
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Full Name",
+ "read_only": 1,
+ "search_index": 1
+ },
+ {
+ "fieldname": "naming_series",
+ "fieldtype": "Select",
+ "label": "Series",
+ "options": "HLC-PRAC-.YYYY.-",
"report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "set_only_once": 1
+ },
+ {
+ "fieldname": "gender",
+ "fieldtype": "Link",
+ "label": "Gender",
+ "options": "Gender"
+ },
+ {
+ "fieldname": "employee_and_user_details_section",
+ "fieldtype": "Section Break",
+ "label": "Employee and User Details"
+ },
+ {
+ "fieldname": "column_break_17",
+ "fieldtype": "Column Break"
+ },
+ {
+ "default": "Active",
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "in_list_view": 1,
+ "label": "Status",
+ "options": "\nActive\nDisabled",
+ "reqd": 1
+ },
+ {
+ "fieldname": "basic_details_section",
+ "fieldtype": "Section Break",
+ "label": "Basic Details"
+ },
+ {
+ "collapsible": 1,
+ "depends_on": "eval: !doc.__islocal",
+ "fieldname": "address_and_contacts_section",
+ "fieldtype": "Section Break",
+ "label": "Address and Contacts"
}
],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
"image_field": "image",
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-11-23 08:54:51.442105",
+ "links": [],
+ "modified": "2020-04-06 13:44:24.759623",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Healthcare Practitioner",
- "name_case": "",
"owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "cancel": 0,
"create": 1,
- "delete": 0,
"email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Laboratory User",
- "set_user_permissions": 0,
"share": 1,
- "submit": 0,
"write": 1
},
{
- "amend": 0,
- "cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Physician",
- "set_user_permissions": 0,
"share": 1,
- "submit": 0,
"write": 1
},
{
- "amend": 0,
- "cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Nursing User",
- "set_user_permissions": 0,
"share": 1,
- "submit": 0,
"write": 1
}
],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
"restrict_to_domain": "Healthcare",
- "search_fields": "first_name,mobile_phone,office_phone",
+ "search_fields": "practitioner_name, mobile_phone, office_phone",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
- "title_field": "first_name",
- "track_changes": 1,
- "track_seen": 0,
- "track_views": 0
+ "title_field": "practitioner_name",
+ "track_changes": 1
}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py
index ad32e94..0c13b6a 100644
--- a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py
+++ b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py
@@ -5,10 +5,10 @@
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
-from frappe import throw, _
-from frappe.utils import cstr
+from frappe import _
from erpnext.accounts.party import validate_party_accounts
from frappe.contacts.address_and_contact import load_address_and_contact, delete_contact_and_address
+from frappe.model.naming import append_number_if_name_exists
from frappe.desk.reportview import build_match_conditions, get_filters_cond
class HealthcarePractitioner(Document):
@@ -16,63 +16,66 @@
load_address_and_contact(self)
def autoname(self):
- # practitioner first_name and last_name
- self.name = " ".join(filter(None,
- [cstr(self.get(f)).strip() for f in ["first_name","middle_name","last_name"]]))
+ # concat first and last name
+ self.name = self.practitioner_name
+
+ if frappe.db.exists('Healthcare Practitioner', self.name):
+ self.name = append_number_if_name_exists('Contact', self.name)
def validate(self):
+ self.set_full_name()
validate_party_accounts(self)
if self.inpatient_visit_charge_item:
- validate_service_item(self.inpatient_visit_charge_item, "Configure a service Item for Inpatient Visit Charge Item")
+ validate_service_item(self.inpatient_visit_charge_item, 'Configure a service Item for Inpatient Consulting Charge Item')
if self.op_consulting_charge_item:
- validate_service_item(self.op_consulting_charge_item, "Configure a service Item for Out Patient Consulting Charge Item")
+ validate_service_item(self.op_consulting_charge_item, 'Configure a service Item for Out Patient Consulting Charge Item')
if self.user_id:
- self.validate_for_enabled_user_id()
- self.validate_duplicate_user_id()
- existing_user_id = frappe.db.get_value("Healthcare Practitioner", self.name, "user_id")
- if self.user_id != existing_user_id:
- frappe.permissions.remove_user_permission(
- "Healthcare Practitioner", self.name, existing_user_id)
-
+ self.validate_user_id()
else:
- existing_user_id = frappe.db.get_value("Healthcare Practitioner", self.name, "user_id")
+ existing_user_id = frappe.db.get_value('Healthcare Practitioner', self.name, 'user_id')
if existing_user_id:
frappe.permissions.remove_user_permission(
- "Healthcare Practitioner", self.name, existing_user_id)
+ 'Healthcare Practitioner', self.name, existing_user_id)
def on_update(self):
if self.user_id:
- frappe.permissions.add_user_permission("Healthcare Practitioner", self.name, self.user_id)
+ frappe.permissions.add_user_permission('Healthcare Practitioner', self.name, self.user_id)
+ def set_full_name(self):
+ if self.last_name:
+ self.practitioner_name = ' '.join(filter(None, [self.first_name, self.last_name]))
+ else:
+ self.practitioner_name = self.first_name
- def validate_for_enabled_user_id(self):
- enabled = frappe.db.get_value("User", self.user_id, "enabled")
- if enabled is None:
- frappe.throw(_("User {0} does not exist").format(self.user_id))
- if enabled == 0:
- frappe.throw(_("User {0} is disabled").format(self.user_id))
+ def validate_user_id(self):
+ if not frappe.db.exists('User', self.user_id):
+ frappe.throw(_('User {0} does not exist').format(self.user_id))
+ elif not frappe.db.exists('User', self.user_id, 'enabled'):
+ frappe.throw(_('User {0} is disabled').format(self.user_id))
- def validate_duplicate_user_id(self):
- practitioner = frappe.db.sql_list("""select name from `tabHealthcare Practitioner` where
- user_id=%s and name!=%s""", (self.user_id, self.name))
+ # check duplicate
+ practitioner = frappe.db.exists('Healthcare Practitioner', {
+ 'user_id': self.user_id,
+ 'name': ('!=', self.name)
+ })
if practitioner:
- throw(_("User {0} is already assigned to Healthcare Practitioner {1}").format(
- self.user_id, practitioner[0]), frappe.DuplicateEntryError)
+ frappe.throw(_('User {0} is already assigned to Healthcare Practitioner {1}').format(
+ self.user_id, practitioner))
def on_trash(self):
delete_contact_and_address('Healthcare Practitioner', self.name)
def validate_service_item(item, msg):
- if frappe.db.get_value("Item", item, "is_stock_item") == 1:
+ if frappe.db.get_value('Item', item, 'is_stock_item'):
frappe.throw(_(msg))
def get_practitioner_list(doctype, txt, searchfield, start, page_len, filters=None):
- fields = ["name", "first_name", "mobile_phone"]
+ fields = ['name', 'practitioner_name', 'mobile_phone']
filters = {
- 'name': ("like", "%%%s%%" % txt)
+ 'name': ('like', '%%%s%%' % txt)
}
- return frappe.get_all("Healthcare Practitioner", fields = fields,
- filters = filters, start=start, page_length=page_len, order_by="name, first_name", as_list=1)
+ return frappe.get_all('Healthcare Practitioner', fields = fields,
+ filters = filters, start=start, page_length=page_len, order_by='name, practitioner_name', as_list=1)
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner_dashboard.py b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner_dashboard.py
index 70c0b3c..bcee444 100644
--- a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner_dashboard.py
+++ b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner_dashboard.py
@@ -9,7 +9,11 @@
'transactions': [
{
'label': _('Appointments and Patient Encounters'),
- 'items': ['Patient Appointment', 'Patient Encounter']
+ 'items': ['Patient Appointment', 'Patient Encounter', 'Fee Validity']
+ },
+ {
+ 'label': _('Consultation'),
+ 'items': ['Clinical Procedure', 'Lab Test']
}
]
}
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.js b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.js
index 8480a52..2cdd550 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.js
+++ b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.js
@@ -3,7 +3,7 @@
frappe.ui.form.on('Healthcare Service Unit', {
onload: function(frm) {
- frm.list_route = "Tree/Healthcare Service Unit";
+ frm.list_route = 'Tree/Healthcare Service Unit';
// get query select healthcare service unit
frm.fields_dict['parent_healthcare_service_unit'].get_query = function(doc) {
@@ -16,32 +16,32 @@
};
},
refresh: function(frm) {
- frm.trigger("set_root_readonly");
- frm.set_df_property("service_unit_type", "reqd", 1);
- frm.add_custom_button(__("Healthcare Service Unit Tree"), function() {
- frappe.set_route("Tree", "Healthcare Service Unit");
+ frm.trigger('set_root_readonly');
+ frm.set_df_property('service_unit_type', 'reqd', 1);
+ frm.add_custom_button(__('Healthcare Service Unit Tree'), function() {
+ frappe.set_route('Tree', 'Healthcare Service Unit');
});
},
set_root_readonly: function(frm) {
// read-only for root healthcare service unit
- frm.set_intro("");
- if(!frm.doc.parent_healthcare_service_unit) {
+ frm.set_intro('');
+ if (!frm.doc.parent_healthcare_service_unit) {
frm.set_read_only();
- frm.set_intro(__("This is a root healthcare service unit and cannot be edited."), true);
+ frm.set_intro(__('This is a root healthcare service unit and cannot be edited.'), true);
}
},
allow_appointments: function(frm) {
- if(!frm.doc.allow_appointments){
- frm.set_value("overlap_appointments", false);
+ if (!frm.doc.allow_appointments) {
+ frm.set_value('overlap_appointments', false);
}
},
is_group: function(frm) {
- if(frm.doc.is_group == 1){
- frm.set_value("allow_appointments", false);
- frm.set_df_property("service_unit_type", "reqd", 0);
+ if (frm.doc.is_group == 1) {
+ frm.set_value('allow_appointments', false);
+ frm.set_df_property('service_unit_type', 'reqd', 0);
}
- else{
- frm.set_df_property("service_unit_type", "reqd", 1);
+ else {
+ frm.set_df_property('service_unit_type', 'reqd', 1);
}
}
});
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json
index 8601f69..ea4ae84 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json
+++ b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json
@@ -9,6 +9,7 @@
"doctype": "DocType",
"document_type": "Setup",
"editable_grid": 1,
+ "engine": "InnoDB",
"field_order": [
"healthcare_service_unit_name",
"parent_healthcare_service_unit",
@@ -18,6 +19,7 @@
"overlap_appointments",
"inpatient_occupancy",
"occupancy_status",
+ "column_break_9",
"warehouse",
"company",
"lft",
@@ -99,10 +101,14 @@
"fieldtype": "Select",
"label": "Occupancy Status",
"no_copy": 1,
- "options": "Vacant\nOccupied",
+ "options": "\nVacant\nOccupied",
"read_only": 1
},
{
+ "fieldname": "column_break_9",
+ "fieldtype": "Column Break"
+ },
+ {
"bold": 1,
"depends_on": "eval:doc.is_group != 1",
"fieldname": "warehouse",
@@ -153,13 +159,11 @@
"report_hide": 1
}
],
- "is_tree": 1,
"links": [],
- "modified": "2020-03-18 18:02:23.713439",
+ "modified": "2020-03-26 16:13:08.675952",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Healthcare Service Unit",
- "nsm_parent_field": "parent_healthcare_service_unit",
"owner": "Administrator",
"permissions": [
{
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.py b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.py
index b408693..13cc43d 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.py
+++ b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.py
@@ -23,9 +23,9 @@
self.validate_one_root()
def validate(self):
- if self.is_group == 1:
+ if self.is_group:
self.allow_appointments = 0
self.overlap_appointments = 0
self.inpatient_occupancy = 0
- elif self.allow_appointments != 1:
+ elif not self.allow_appointments:
self.overlap_appointments = 0
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.js b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.js
index 288ebc4..eb33ab6 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.js
+++ b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.js
@@ -2,118 +2,85 @@
// For license information, please see license.txt
frappe.ui.form.on('Healthcare Service Unit Type', {
+ refresh: function(frm) {
+ frm.set_df_property('item_code', 'read_only', frm.doc.__islocal ? 0 : 1);
+ if (!frm.doc.__islocal && frm.doc.is_billable) {
+ frm.add_custom_button(__('Change Item Code'), function() {
+ change_item_code(cur_frm, frm.doc);
+ });
+ }
+ },
+
service_unit_type: function(frm) {
set_item_details(frm);
- if(!frm.doc.__islocal){
+
+ if (!frm.doc.__islocal) {
frm.doc.change_in_item = 1;
}
},
+
is_billable: function(frm) {
set_item_details(frm);
},
- refresh: function(frm) {
- frm.set_df_property("item_code", "read_only", frm.doc.__islocal ? 0 : 1);
- if(!frm.doc.__islocal) {
- frm.add_custom_button(__('Change Item Code'), function() {
- change_item_code(cur_frm,frm.doc);
- } );
- if(frm.doc.disabled == 1){
- frm.add_custom_button(__('Enable'), function() {
- enable(cur_frm);
- } );
- }
- else{
- frm.add_custom_button(__('Disable'), function() {
- disable(cur_frm);
- } );
- }
- }
- },
+
rate: function(frm) {
- if(!frm.doc.__islocal){
+ if (!frm.doc.__islocal) {
frm.doc.change_in_item = 1;
}
},
item_group: function(frm) {
- if(!frm.doc.__islocal){
+ if (!frm.doc.__islocal) {
frm.doc.change_in_item = 1;
}
},
description: function(frm) {
- if(!frm.doc.__islocal){
+ if (!frm.doc.__islocal) {
frm.doc.change_in_item = 1;
}
}
});
-var disable = function(frm){
- var doc = frm.doc;
- frappe.call({
- method: "erpnext.healthcare.doctype.healthcare_service_unit_type.healthcare_service_unit_type.disable_enable",
- args: {status: 1, doc_name: doc.name, item: doc.item, is_billable: doc.is_billable},
- callback: function(){
- cur_frm.reload_doc();
- }
- });
+let set_item_details = function(frm) {
+ if (frm.doc.service_unit_type && frm.doc.is_billable) {
+ if (!frm.doc.item_code)
+ frm.set_value('item_code', frm.doc.service_unit_type);
+ if (!frm.doc.description)
+ frm.set_value('description', frm.doc.service_unit_type);
+ if (!frm.doc.item_group)
+ frm.set_value('item_group', 'Services');
+ }
};
-var enable = function(frm){
- var doc = frm.doc;
- frappe.call({
- method: "erpnext.healthcare.doctype.healthcare_service_unit_type.healthcare_service_unit_type.disable_enable",
- args: {status: 0, doc_name: doc.name, item: doc.item, is_billable: doc.is_billable},
- callback: function(){
- cur_frm.reload_doc();
- }
- });
-};
-
-var change_item_code = function(frm, doc){
- var d = new frappe.ui.Dialog({
- title:__("Change Item Code"),
- fields:[
+let change_item_code = function(frm, doc) {
+ let d = new frappe.ui.Dialog({
+ title: __('Change Item Code'),
+ fields: [
{
- "fieldtype": "Data",
- "label": "Item Code",
- "fieldname": "Item Code",
- reqd:1
- },
- {
- "fieldtype": "Button",
- "label": __("Change Code"),
- click: function() {
- var values = d.get_values();
- if(!values)
- return;
- change_item_code_from_unit_type(values["Item Code"], doc);
- d.hide();
- }
+ 'fieldtype': 'Data',
+ 'label': 'Item Code',
+ 'fieldname': 'item_code',
+ 'default': doc.item_code,
+ reqd: 1,
}
- ]
+ ],
+ primary_action: function() {
+ let values = d.get_values();
+ if (values) {
+ frappe.call({
+ "method": "erpnext.healthcare.doctype.healthcare_service_unit_type.healthcare_service_unit_type.change_item_code",
+ "args": {item: doc.item, item_code: values['item_code'], doc_name: doc.name},
+ callback: function () {
+ frm.reload_doc();
+ }
+ });
+ }
+ d.hide();
+ },
+ primary_action_label: __("Change Template Code")
});
+
d.show();
d.set_values({
'Item Code': frm.doc.item_code
});
-
- var change_item_code_from_unit_type = function(item_code, doc){
- frappe.call({
- "method": "erpnext.healthcare.doctype.healthcare_service_unit_type.healthcare_service_unit_type.change_item_code",
- "args": {item: doc.item, item_code: item_code, doc_name: doc.name},
- callback: function () {
- frm.reload_doc();
- }
- });
- };
-};
-
-var set_item_details = function(frm) {
- if(frm.doc.service_unit_type && frm.doc.is_billable == 1){
- if(!frm.doc.item_code)
- frm.set_value("item_code", frm.doc.service_unit_type);
- if(!frm.doc.description)
- frm.set_value("description", frm.doc.service_unit_type);
- if(!frm.doc.item_group)
- frm.set_value("item_group", 'Services');
- }
};
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.json b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.json
index 40681e9..5fa47d9 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.json
+++ b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.json
@@ -1,588 +1,164 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 1,
- "allow_rename": 1,
- "autoname": "field:service_unit_type",
- "beta": 0,
- "creation": "2018-07-11 16:47:51.414675",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "actions": [],
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "field:service_unit_type",
+ "creation": "2018-07-11 16:47:51.414675",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "disabled",
+ "service_unit_type",
+ "allow_appointments",
+ "overlap_appointments",
+ "inpatient_occupancy",
+ "is_billable",
+ "item_details",
+ "item",
+ "item_code",
+ "item_group",
+ "uom",
+ "no_of_hours",
+ "column_break_11",
+ "rate",
+ "description",
+ "change_in_item"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "service_unit_type",
- "fieldtype": "Data",
- "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": "Service Unit Type",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "fieldname": "service_unit_type",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Service Unit Type",
+ "reqd": 1,
"unique": 1
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 1,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "depends_on": "eval:doc.inpatient_occupancy != 1",
- "fieldname": "allow_appointments",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Allow Appointments",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "bold": 1,
+ "default": "0",
+ "depends_on": "eval:doc.inpatient_occupancy != 1",
+ "fieldname": "allow_appointments",
+ "fieldtype": "Check",
+ "label": "Allow Appointments",
+ "no_copy": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 1,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "depends_on": "eval:doc.allow_appointments == 1 && doc.inpatient_occupany != 1",
- "fieldname": "overlap_appointments",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Allow Overlap",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "bold": 1,
+ "default": "0",
+ "depends_on": "eval:doc.allow_appointments == 1 && doc.inpatient_occupany != 1",
+ "fieldname": "overlap_appointments",
+ "fieldtype": "Check",
+ "label": "Allow Overlap",
+ "no_copy": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 1,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "depends_on": "eval:doc.allow_appointments != 1",
- "fieldname": "inpatient_occupancy",
- "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": "Inpatient Occupancy",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "bold": 1,
+ "default": "0",
+ "depends_on": "eval:doc.allow_appointments != 1",
+ "fieldname": "inpatient_occupancy",
+ "fieldtype": "Check",
+ "label": "Inpatient Occupancy",
+ "no_copy": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 1,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:doc.inpatient_occupancy == 1 && doc.allow_appointments != 1",
- "fieldname": "is_billable",
- "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": "Is Billable",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "bold": 1,
+ "default": "0",
+ "depends_on": "eval:doc.inpatient_occupancy == 1 && doc.allow_appointments != 1",
+ "fieldname": "is_billable",
+ "fieldtype": "Check",
+ "label": "Is Billable"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "is_billable",
- "fieldname": "item_details",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Item Details",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "depends_on": "is_billable",
+ "fieldname": "item_details",
+ "fieldtype": "Section Break",
+ "label": "Item Details"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "item",
- "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": "Item",
- "length": 0,
- "no_copy": 0,
- "options": "Item",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "item",
+ "fieldtype": "Link",
+ "label": "Item",
+ "options": "Item",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "item_code",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Item Code",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "item_code",
+ "fieldtype": "Data",
+ "label": "Item Code",
+ "mandatory_depends_on": "eval: doc.is_billable == 1"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "item_group",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Item Group",
- "length": 0,
- "no_copy": 0,
- "options": "Item Group",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "item_group",
+ "fieldtype": "Link",
+ "label": "Item Group",
+ "mandatory_depends_on": "eval: doc.is_billable == 1",
+ "options": "Item Group"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "uom",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "UOM",
- "length": 0,
- "no_copy": 0,
- "options": "UOM",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "uom",
+ "fieldtype": "Link",
+ "label": "UOM",
+ "mandatory_depends_on": "eval: doc.is_billable == 1",
+ "options": "UOM"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "no_of_hours",
- "fieldtype": "Int",
- "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": "UOM Conversion in Hours",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "no_of_hours",
+ "fieldtype": "Int",
+ "label": "UOM Conversion in Hours",
+ "mandatory_depends_on": "eval: doc.is_billable == 1"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_11",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_11",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "rate",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Rate / UOM",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "rate",
+ "fieldtype": "Currency",
+ "label": "Rate / UOM"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "disabled",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Disabled",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "disabled",
+ "fieldtype": "Check",
+ "label": "Disabled",
+ "no_copy": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "description",
- "fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Description",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "description",
+ "fieldtype": "Small Text",
+ "label": "Description"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "change_in_item",
- "fieldtype": "Check",
- "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": "Change in Item",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "default": "0",
+ "fieldname": "change_in_item",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "label": "Change in Item"
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-08-08 13:00:23.751635",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Healthcare Service Unit Type",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "links": [],
+ "modified": "2020-01-30 16:06:00.624496",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Healthcare Service Unit Type",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Healthcare Administrator",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Healthcare Administrator",
+ "share": 1,
"write": 1
}
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "service_unit_type",
- "track_changes": 0,
- "track_seen": 0,
- "track_views": 0
+ ],
+ "restrict_to_domain": "Healthcare",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "service_unit_type"
}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py
index 43f01c8..286ecc0 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py
+++ b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py
@@ -10,109 +10,107 @@
class HealthcareServiceUnitType(Document):
def validate(self):
- if self.is_billable == 1:
- if not self.uom or not self.item_group or not self.description or not self.no_of_hours > 0:
- frappe.throw(_("Configure Item Fields like UOM, Item Group, Description and No of Hours."))
+ if self.is_billable:
+ if self.disabled:
+ frappe.db.set_value('Item', self.item, 'disabled', 1)
+ else:
+ frappe.db.set_value('Item', self.item, 'disabled', 0)
def after_insert(self):
if self.inpatient_occupancy and self.is_billable:
create_item(self)
def on_trash(self):
- if(self.item):
+ if self.item:
try:
- frappe.delete_doc("Item",self.item)
+ frappe.delete_doc('Item', self.item)
except Exception:
- frappe.throw(_("""Not permitted. Please disable the Service Unit Type"""))
+ frappe.throw(_('Not permitted. Please disable the Service Unit Type'))
def on_update(self):
- if(self.change_in_item and self.is_billable == 1 and self.item):
- updating_item(self)
- item_price = item_price_exist(self)
- if not item_price:
- if(self.rate != 0.0):
- price_list_name = frappe.db.get_value("Price List", {"selling": 1})
- if(self.rate):
- make_item_price(self.item_code, price_list_name, self.rate)
- else:
- make_item_price(self.item_code, price_list_name, 0.0)
- else:
- frappe.db.set_value("Item Price", item_price, "price_list_rate", self.rate)
+ if self.change_in_item and self.is_billable and self.item:
+ update_item(self)
- frappe.db.set_value(self.doctype,self.name,"change_in_item",0)
- elif(self.is_billable == 0 and self.item):
- frappe.db.set_value("Item",self.item,"disabled",1)
+ item_price = item_price_exists(self)
+
+ if not item_price:
+ price_list_name = frappe.db.get_value('Price List', {'selling': 1})
+ if self.rate:
+ make_item_price(self.item_code, price_list_name, self.rate)
+ else:
+ make_item_price(self.item_code, price_list_name, 0.0)
+ else:
+ frappe.db.set_value('Item Price', item_price, 'price_list_rate', self.rate)
+
+ frappe.db.set_value(self.doctype, self.name, 'change_in_item',0)
+ elif not self.is_billable and self.item:
+ frappe.db.set_value('Item', self.item, 'disabled', 1)
self.reload()
-def item_price_exist(doc):
- item_price = frappe.db.exists({
- "doctype": "Item Price",
- "item_code": doc.item_code})
- if(item_price):
- return item_price[0][0]
- else:
- return False
-def updating_item(doc):
- frappe.db.sql("""update `tabItem` set item_name=%s, item_group=%s, disabled=0, standard_rate=%s,
- description=%s, modified=NOW() where item_code=%s""",
- (doc.service_unit_type, doc.item_group , doc.rate, doc.description, doc.item))
+def item_price_exists(doc):
+ item_price = frappe.db.exists({'doctype': 'Item Price', 'item_code': doc.item_code})
+ if len(item_price):
+ return item_price[0][0]
+ return False
def create_item(doc):
- #insert item
+ # insert item
item = frappe.get_doc({
- "doctype": "Item",
- "item_code": doc.item_code,
- "item_name":doc.service_unit_type,
- "item_group": doc.item_group,
- "description":doc.description,
- "is_sales_item": 1,
- "is_service_item": 1,
- "is_purchase_item": 0,
- "is_stock_item": 0,
- "show_in_website": 0,
- "is_pro_applicable": 0,
- "disabled": 0,
- "stock_uom": doc.uom
- }).insert(ignore_permissions=True)
+ 'doctype': 'Item',
+ 'item_code': doc.item_code,
+ 'item_name': doc.service_unit_type,
+ 'item_group': doc.item_group,
+ 'description': doc.description or doc.item_code,
+ 'is_sales_item': 1,
+ 'is_service_item': 1,
+ 'is_purchase_item': 0,
+ 'is_stock_item': 0,
+ 'show_in_website': 0,
+ 'is_pro_applicable': 0,
+ 'disabled': 0,
+ 'stock_uom': doc.uom
+ }).insert(ignore_permissions=True, ignore_mandatory=True)
- #insert item price
- #get item price list to insert item price
- if(doc.rate != 0.0):
- price_list_name = frappe.db.get_value("Price List", {"selling": 1})
- if(doc.rate):
- make_item_price(item.name, price_list_name, doc.rate)
- item.standard_rate = doc.rate
- else:
- make_item_price(item.name, price_list_name, 0.0)
- item.standard_rate = 0.0
- item.save(ignore_permissions = True)
- #Set item to the Doc
- frappe.db.set_value("Healthcare Service Unit Type", doc.name, "item", item.name)
+ # insert item price
+ # get item price list to insert item price
+ price_list_name = frappe.db.get_value('Price List', {'selling': 1})
+ if doc.rate:
+ make_item_price(item.name, price_list_name, doc.rate)
+ item.standard_rate = doc.rate
+ else:
+ make_item_price(item.name, price_list_name, 0.0)
+ item.standard_rate = 0.0
- doc.reload() #refresh the doc after insert.
+ item.save(ignore_permissions=True)
+
+ # Set item in the doc
+ doc.db_set('item', item.name)
def make_item_price(item, price_list_name, item_price):
frappe.get_doc({
- "doctype": "Item Price",
- "price_list": price_list_name,
- "item_code": item,
- "price_list_rate": item_price
- }).insert(ignore_permissions=True)
+ 'doctype': 'Item Price',
+ 'price_list': price_list_name,
+ 'item_code': item,
+ 'price_list_rate': item_price
+ }).insert(ignore_permissions=True, ignore_mandatory=True)
+
+def update_item(doc):
+ item = frappe.get_doc("Item", doc.item)
+ if item:
+ item.update({
+ "item_name": doc.service_unit_type,
+ "item_group": doc.item_group,
+ "disabled": 0,
+ "standard_rate": doc.rate,
+ "description": doc.description
+ })
+ item.db_update()
@frappe.whitelist()
def change_item_code(item, item_code, doc_name):
- item_exist = frappe.db.exists({
- "doctype": "Item",
- "item_code": item_code})
- if(item_exist):
- frappe.throw(_("Code {0} already exist").format(item_code))
+ if frappe.db.exists({'doctype': 'Item', 'item_code': item_code}):
+ frappe.throw(_('Item with Item Code {0} already exists').format(item_code))
else:
- rename_doc("Item", item, item_code, ignore_permissions=True)
- frappe.db.set_value("Healthcare Service Unit Type", doc_name, "item_code", item_code)
-
-@frappe.whitelist()
-def disable_enable(status, doc_name, item=None, is_billable=None):
- frappe.db.set_value("Healthcare Service Unit Type", doc_name, "disabled", status)
- if(is_billable == 1):
- frappe.db.set_value("Item", item, "disabled", status)
+ rename_doc('Item', item, item_code, ignore_permissions=True)
+ frappe.db.set_value('Healthcare Service Unit Type', doc_name, 'item_code', item_code)
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type_dashboard.py b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type_dashboard.py
new file mode 100644
index 0000000..0ac548b
--- /dev/null
+++ b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type_dashboard.py
@@ -0,0 +1,13 @@
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+ return {
+ 'fieldname': 'service_unit_type',
+ 'transactions': [
+ {
+ 'label': _('Healthcare Service Units'),
+ 'items': ['Healthcare Service Unit']
+ },
+ ]
+ }
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/test_healthcare_service_unit_type.py b/erpnext/healthcare/doctype/healthcare_service_unit_type/test_healthcare_service_unit_type.py
index 3c5b64f..01cf4b0 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit_type/test_healthcare_service_unit_type.py
+++ b/erpnext/healthcare/doctype/healthcare_service_unit_type/test_healthcare_service_unit_type.py
@@ -3,6 +3,31 @@
# See license.txt
from __future__ import unicode_literals
import unittest
+import frappe
class TestHealthcareServiceUnitType(unittest.TestCase):
- pass
+ def test_item_creation(self):
+ unit_type = get_unit_type()
+ self.assertTrue(frappe.db.exists('Item', unit_type.item))
+
+ # check item disabled
+ unit_type.disabled = 1
+ unit_type.save()
+ self.assertEqual(frappe.db.get_value('Item', unit_type.item, 'disabled'), 1)
+
+
+def get_unit_type():
+ if frappe.db.exists('Healthcare Service Unit Type', 'Inpatient Rooms'):
+ return frappe.get_doc('Healthcare Service Unit Type', 'Inpatient Rooms')
+
+ unit_type = frappe.new_doc('Healthcare Service Unit Type')
+ unit_type.service_unit_type = 'Inpatient Rooms'
+ unit_type.inpatient_occupancy = 1
+ unit_type.is_billable = 1
+ unit_type.item_code = 'Inpatient Rooms'
+ unit_type.item_group = 'Services'
+ unit_type.uom = 'Hour'
+ unit_type.no_of_hours = 1
+ unit_type.rate = 4000
+ unit_type.save()
+ return unit_type
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json
index 95d9e44..de08620 100644
--- a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json
+++ b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json
@@ -7,40 +7,40 @@
"engine": "InnoDB",
"field_order": [
"sb_op_settings",
- "patient_master_name",
- "manage_customer",
+ "patient_name_by",
+ "link_customer_to_patient",
"default_medical_code_standard",
"column_break_9",
"collect_registration_fee",
"registration_fee",
- "manage_appointment_invoice_automatically",
- "max_visit",
+ "automate_appointment_invoicing",
+ "enable_free_follow_ups",
+ "max_visits",
"valid_days",
"healthcare_service_items",
"inpatient_visit_charge_item",
"op_consulting_charge_item",
"column_break_13",
"clinical_procedure_consumable_item",
- "out_patient_sms_alerts",
- "reg_sms",
- "reg_msg",
- "app_con",
- "app_con_msg",
- "no_con",
- "column_break_16",
- "app_rem",
- "app_rem_msg",
- "rem_before",
"sb_in_ac",
"income_account",
- "sb_r_ac",
"receivable_account",
+ "out_patient_sms_alerts",
+ "send_registration_msg",
+ "registration_msg",
+ "send_appointment_confirmation",
+ "appointment_confirmation_msg",
+ "avoid_confirmation",
+ "column_break_16",
+ "send_appointment_reminder",
+ "appointment_reminder_msg",
+ "remind_before",
"sb_lab_settings",
- "create_test_on_si_submit",
- "require_sample_collection",
- "require_test_result_approval",
+ "create_lab_test_on_si_submit",
+ "create_sample_collection_for_lab_test",
"column_break_34",
"employee_name_and_designation_in_print",
+ "lab_test_approval_required",
"custom_signature_in_print",
"laboratory_sms_alerts",
"sms_printed",
@@ -54,19 +54,6 @@
"label": "Out Patient Settings"
},
{
- "fieldname": "patient_master_name",
- "fieldtype": "Select",
- "label": "Patient Name By",
- "options": "Patient Name\nNaming Series"
- },
- {
- "default": "1",
- "description": "If checked, a customer will be created, mapped to Patient.\nPatient Invoices will be created against this Customer. You can also select existing Customer while creating Patient.",
- "fieldname": "manage_customer",
- "fieldtype": "Check",
- "label": "Manage Customer"
- },
- {
"fieldname": "default_medical_code_standard",
"fieldtype": "Link",
"label": "Default Medical Code Standard",
@@ -78,6 +65,7 @@
},
{
"default": "0",
+ "description": "Checking this will create new Patients with a Disabled status by default and will only be enabled after invoicing the Registration Fee.",
"fieldname": "collect_registration_fee",
"fieldtype": "Check",
"label": "Collect Fee for Patient Registration"
@@ -91,27 +79,19 @@
"options": "Currency"
},
{
- "default": "0",
- "description": "Manage Appointment Invoice submit and cancel automatically for Patient Encounter",
- "fieldname": "manage_appointment_invoice_automatically",
- "fieldtype": "Check",
- "label": "Invoice Appointments Automatically"
- },
- {
- "fieldname": "max_visit",
- "fieldtype": "Int",
- "label": "Patient Encounters in valid days"
- },
- {
+ "depends_on": "eval:doc.enable_free_follow_ups == 1",
+ "description": "Time period (Valid number of days) for free consultations",
"fieldname": "valid_days",
"fieldtype": "Int",
- "label": "Valid number of days"
+ "label": "Valid Number of Days",
+ "mandatory_depends_on": "eval:doc.enable_free_follow_ups == 1"
},
{
"collapsible": 1,
+ "description": "You can configure default Items for billing consultation charges, procedure consumption items and inpatient visits",
"fieldname": "healthcare_service_items",
"fieldtype": "Section Break",
- "label": "Healthcare Service Items"
+ "label": "Default Healthcare Service Items"
},
{
"fieldname": "inpatient_visit_charge_item",
@@ -142,86 +122,24 @@
"label": "Out Patient SMS Alerts"
},
{
- "default": "0",
- "fieldname": "reg_sms",
- "fieldtype": "Check",
- "label": "Patient Registration"
- },
- {
- "default": "Hello {{doc.patient}}, Thank you for registering with {{doc.company}}. Your ID is {{doc.id}} . Please note this ID for future reference. \nThank You, Get well soon!",
- "depends_on": "reg_sms",
- "fieldname": "reg_msg",
- "fieldtype": "Small Text",
- "ignore_xss_filter": 1,
- "label": "Registration Message"
- },
- {
- "default": "0",
- "fieldname": "app_con",
- "fieldtype": "Check",
- "label": "Appointment Confirmation"
- },
- {
- "default": "Hello {{doc.patient}}, You have scheduled an appointment with {{doc.practitioner}} by {{doc.start_dt}} at {{doc.company}}.\nThank you, Good day!",
- "depends_on": "app_con",
- "fieldname": "app_con_msg",
- "fieldtype": "Small Text",
- "ignore_xss_filter": 1,
- "label": "Confirmation Message"
- },
- {
- "default": "0",
- "depends_on": "app_con",
- "description": "Do not confirm if appointment is created for the same day",
- "fieldname": "no_con",
- "fieldtype": "Check",
- "label": "Avoid Confirmation"
- },
- {
"fieldname": "column_break_16",
"fieldtype": "Column Break"
},
{
- "default": "0",
- "fieldname": "app_rem",
- "fieldtype": "Check",
- "label": "Appointment Reminder"
- },
- {
- "default": "Hello {{doc.patient}}, You have an appointment with {{doc.practitioner}} by {{doc.appointment_time}} at {{doc.company}}.\nThank you, Good day!\n",
- "depends_on": "app_rem",
- "fieldname": "app_rem_msg",
- "fieldtype": "Small Text",
- "ignore_xss_filter": 1,
- "label": "Reminder Message"
- },
- {
- "depends_on": "app_rem",
- "fieldname": "rem_before",
- "fieldtype": "Time",
- "label": "Remind Before"
- },
- {
"collapsible": 1,
- "description": "Default income accounts to be used if not set in Healthcare Practitioner to book Appointment charges.",
"fieldname": "sb_in_ac",
"fieldtype": "Section Break",
- "label": "Income Account"
+ "label": "Default Accounts"
},
{
+ "description": "Default income accounts to be used if not set in Healthcare Practitioner to book Appointment charges.",
"fieldname": "income_account",
"fieldtype": "Table",
"label": "Income Account",
"options": "Party Account"
},
{
- "collapsible": 1,
- "description": "Default receivable accounts to be used if not set in Patient to book Appointment charges.",
- "fieldname": "sb_r_ac",
- "fieldtype": "Section Break",
- "label": "Receivable Account"
- },
- {
+ "description": "Default receivable accounts to be used to book Appointment charges.",
"fieldname": "receivable_account",
"fieldtype": "Table",
"label": "Receivable Account",
@@ -234,30 +152,12 @@
"label": "Laboratory Settings"
},
{
- "default": "0",
- "fieldname": "create_test_on_si_submit",
- "fieldtype": "Check",
- "label": "Create Lab Test(s) on Sales Invoice Submit"
- },
- {
- "default": "0",
- "description": "Create documents for sample collection",
- "fieldname": "require_sample_collection",
- "fieldtype": "Check",
- "label": "Manage Sample Collection"
- },
- {
- "default": "0",
- "fieldname": "require_test_result_approval",
- "fieldtype": "Check",
- "label": "Require Lab Test Approval"
- },
- {
"fieldname": "column_break_34",
"fieldtype": "Column Break"
},
{
"default": "1",
+ "description": "Check this if you want the Name and Designation of the Employee associated with the User who submits the document to be printed in the Lab Test Report.",
"fieldname": "employee_name_and_designation_in_print",
"fieldtype": "Check",
"label": "Employee name and designation in print"
@@ -279,7 +179,7 @@
"fieldname": "sms_printed",
"fieldtype": "Small Text",
"ignore_xss_filter": 1,
- "label": "Result Printed"
+ "label": "Result Printed Message"
},
{
"fieldname": "column_break_28",
@@ -290,12 +190,123 @@
"fieldname": "sms_emailed",
"fieldtype": "Small Text",
"ignore_xss_filter": 1,
- "label": "Result Emailed"
+ "label": "Result Emailed Message"
+ },
+ {
+ "default": "0",
+ "description": "Checking this will restrict printing and emailing of Lab Test documents unless they have the status as Approved.",
+ "fieldname": "lab_test_approval_required",
+ "fieldtype": "Check",
+ "label": "Do not print or email Lab Tests without Approval"
+ },
+ {
+ "default": "1",
+ "description": "If checked, a customer will be created, mapped to Patient.\nPatient Invoices will be created against this Customer. You can also select existing Customer while creating Patient.",
+ "fieldname": "link_customer_to_patient",
+ "fieldtype": "Check",
+ "label": "Link Customer to Patient"
+ },
+ {
+ "default": "0",
+ "description": "Checking this will create Lab Test(s) specified in the Sales Invoice on submission.",
+ "fieldname": "create_lab_test_on_si_submit",
+ "fieldtype": "Check",
+ "label": "Create Lab Test(s) on Sales Invoice Submission"
+ },
+ {
+ "default": "0",
+ "description": "Checking this will create a Sample Collection document every time you create a Lab Test",
+ "fieldname": "create_sample_collection_for_lab_test",
+ "fieldtype": "Check",
+ "label": "Create Sample Collection document for Lab Test"
+ },
+ {
+ "fieldname": "patient_name_by",
+ "fieldtype": "Select",
+ "label": "Patient Name By",
+ "options": "Patient Name\nNaming Series"
+ },
+ {
+ "default": "0",
+ "description": "Manage Appointment Invoice submit and cancel automatically for Patient Encounter",
+ "fieldname": "automate_appointment_invoicing",
+ "fieldtype": "Check",
+ "label": "Automate Appointment Invoicing"
+ },
+ {
+ "default": "0",
+ "fieldname": "send_registration_msg",
+ "fieldtype": "Check",
+ "label": "Patient Registration"
+ },
+ {
+ "default": "Hello {{doc.patient}}, Thank you for registering with {{doc.company}}. Your ID is {{doc.id}} . Please note this ID for future reference. \nThank You, Get well soon!",
+ "depends_on": "send_registration_msg",
+ "fieldname": "registration_msg",
+ "fieldtype": "Small Text",
+ "ignore_xss_filter": 1,
+ "label": "Registration Message"
+ },
+ {
+ "default": "0",
+ "fieldname": "send_appointment_confirmation",
+ "fieldtype": "Check",
+ "label": "Appointment Confirmation"
+ },
+ {
+ "default": "Hello {{doc.patient}}, You have scheduled an appointment with {{doc.practitioner}} by {{doc.start_dt}} at {{doc.company}}.\nThank you, Good day!",
+ "depends_on": "send_appointment_confirmation",
+ "fieldname": "appointment_confirmation_msg",
+ "fieldtype": "Small Text",
+ "ignore_xss_filter": 1,
+ "label": "Confirmation Message"
+ },
+ {
+ "default": "0",
+ "depends_on": "send_appointment_confirmation",
+ "description": "Do not confirm if appointment is created for the same day",
+ "fieldname": "avoid_confirmation",
+ "fieldtype": "Check",
+ "label": "Avoid Confirmation"
+ },
+ {
+ "default": "0",
+ "fieldname": "send_appointment_reminder",
+ "fieldtype": "Check",
+ "label": "Appointment Reminder"
+ },
+ {
+ "default": "Hello {{doc.patient}}, You have an appointment with {{doc.practitioner}} by {{doc.appointment_time}} at {{doc.company}}.\nThank you, Good day!\n",
+ "depends_on": "send_appointment_reminder",
+ "fieldname": "appointment_reminder_msg",
+ "fieldtype": "Small Text",
+ "ignore_xss_filter": 1,
+ "label": "Reminder Message"
+ },
+ {
+ "depends_on": "send_appointment_reminder",
+ "fieldname": "remind_before",
+ "fieldtype": "Time",
+ "label": "Remind Before"
+ },
+ {
+ "depends_on": "eval:doc.enable_free_follow_ups == 1",
+ "description": "The number of free follow ups (Patient Encounters in valid days) allowed",
+ "fieldname": "max_visits",
+ "fieldtype": "Int",
+ "label": "Number of Patient Encounters in Valid Days",
+ "mandatory_depends_on": "eval:doc.enable_free_follow_ups == 1"
+ },
+ {
+ "default": "0",
+ "fieldname": "enable_free_follow_ups",
+ "fieldtype": "Check",
+ "label": "Enable Free Follow-ups"
}
],
"issingle": 1,
"links": [],
- "modified": "2020-01-23 13:31:43.699711",
+ "modified": "2020-03-26 11:25:21.842092",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Healthcare Settings",
diff --git a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.py b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.py
index 8555e80..a16fceb 100644
--- a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.py
+++ b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.py
@@ -11,69 +11,80 @@
class HealthcareSettings(Document):
def validate(self):
- for key in ["collect_registration_fee","manage_customer","patient_master_name",
- "require_test_result_approval","require_sample_collection", "default_medical_code_standard"]:
+ for key in ['collect_registration_fee', 'link_customer_to_patient', 'patient_name_by',
+ 'lab_test_approval_required', 'create_sample_collection_for_lab_test', 'default_medical_code_standard']:
frappe.db.set_default(key, self.get(key, ""))
- if(self.collect_registration_fee):
- if self.registration_fee <= 0 :
- frappe.throw(_("Registration fee can not be Zero"))
+
+ if self.collect_registration_fee:
+ if self.registration_fee <= 0:
+ frappe.throw(_('Registration Fee cannot be negative or zero'))
+
if self.inpatient_visit_charge_item:
- validate_service_item(self.inpatient_visit_charge_item, "Configure a service Item for Inpatient Visit Charge Item")
+ validate_service_item(self.inpatient_visit_charge_item)
if self.op_consulting_charge_item:
- validate_service_item(self.op_consulting_charge_item, "Configure a service Item for Out Patient Consulting Charge Item")
+ validate_service_item(self.op_consulting_charge_item)
if self.clinical_procedure_consumable_item:
- validate_service_item(self.clinical_procedure_consumable_item, "Configure a service Item for Clinical Procedure Consumable Item")
+ validate_service_item(self.clinical_procedure_consumable_item)
+
+
+def validate_service_item(item):
+ if frappe.db.get_value('Item', item, 'is_stock_item'):
+ frappe.throw(_('Configure a service Item for {0}').format(item))
@frappe.whitelist()
def get_sms_text(doc):
- sms_text = {}
- doc = frappe.get_doc("Lab Test",doc)
- #doc = json.loads(doc)
- context = {"doc": doc, "alert": doc, "comments": None}
- emailed = frappe.db.get_value("Healthcare Settings", None, "sms_emailed")
- sms_text['emailed'] = frappe.render_template(emailed, context)
- printed = frappe.db.get_value("Healthcare Settings", None, "sms_printed")
- sms_text['printed'] = frappe.render_template(printed, context)
- return sms_text
+ sms_text = {}
+ doc = frappe.get_doc('Lab Test', doc)
+ context = {'doc': doc, 'alert': doc, 'comments': None}
+
+ emailed = frappe.db.get_value('Healthcare Settings', None, 'sms_emailed')
+ sms_text['emailed'] = frappe.render_template(emailed, context)
+
+ printed = frappe.db.get_value('Healthcare Settings', None, 'sms_printed')
+ sms_text['printed'] = frappe.render_template(printed, context)
+
+ return sms_text
def send_registration_sms(doc):
- if (frappe.db.get_value("Healthcare Settings", None, "reg_sms")=='1'):
- if doc.mobile:
- context = {"doc": doc, "alert": doc, "comments": None}
- if doc.get("_comments"):
- context["comments"] = json.loads(doc.get("_comments"))
- messages = frappe.db.get_value("Healthcare Settings", None, "reg_msg")
- messages = frappe.render_template(messages, context)
- number = [doc.mobile]
- send_sms(number,messages)
- else:
- frappe.msgprint(doc.name + " Has no mobile number to send registration SMS", alert=True)
-
+ if frappe.db.get_single_value('Healthcare Settings', 'send_registration_msg'):
+ if doc.mobile:
+ context = {'doc': doc, 'alert': doc, 'comments': None}
+ if doc.get('_comments'):
+ context['comments'] = json.loads(doc.get('_comments'))
+ messages = frappe.db.get_single_value('Healthcare Settings', 'registration_msg')
+ messages = frappe.render_template(messages, context)
+ number = [doc.mobile]
+ send_sms(number,messages)
+ else:
+ frappe.msgprint(doc.name + ' has no mobile number to send registration SMS', alert=True)
def get_receivable_account(company):
- receivable_account = get_account(None, "receivable_account", "Healthcare Settings", company)
- if receivable_account:
- return receivable_account
- return frappe.get_cached_value('Company', company, "default_receivable_account")
+ receivable_account = get_account(None, 'receivable_account', 'Healthcare Settings', company)
+ if receivable_account:
+ return receivable_account
+
+ return frappe.get_cached_value('Company', company, 'default_receivable_account')
def get_income_account(practitioner, company):
- if(practitioner):
- income_account = get_account("Healthcare Practitioner", None, practitioner, company)
- if income_account:
- return income_account
- income_account = get_account(None, "income_account", "Healthcare Settings", company)
- if income_account:
- return income_account
- return frappe.get_cached_value('Company', company, "default_income_account")
+ # check income account in Healthcare Practitioner
+ if practitioner:
+ income_account = get_account('Healthcare Practitioner', None, practitioner, company)
+ if income_account:
+ return income_account
+
+ # else check income account in Healthcare Settings
+ income_account = get_account(None, 'income_account', 'Healthcare Settings', company)
+ if income_account:
+ return income_account
+
+ # else return default income account of company
+ return frappe.get_cached_value('Company', company, 'default_income_account')
def get_account(parent_type, parent_field, parent, company):
- if(parent_type):
- return frappe.db.get_value("Party Account",
- {"parenttype": parent_type, "parent": parent, "company": company}, "account")
- if(parent_field):
- return frappe.db.get_value("Party Account",
- {"parentfield": parent_field, "parent": parent, "company": company}, "account")
+ if parent_type:
+ return frappe.db.get_value('Party Account',
+ {'parenttype': parent_type, 'parent': parent, 'company': company}, 'account')
-def validate_service_item(item, msg):
- if frappe.db.get_value("Item", item, "is_stock_item") == 1:
- frappe.throw(_(msg))
+ if parent_field:
+ return frappe.db.get_value('Party Account',
+ {'parentfield': parent_field, 'parent': parent, 'company': company}, 'account')
diff --git a/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
index f10725e..e15324c 100644
--- a/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
+++ b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
@@ -8,11 +8,12 @@
from frappe.utils import now_datetime, today
from frappe.utils.make_random import get_random
from erpnext.healthcare.doctype.inpatient_record.inpatient_record import admit_patient, discharge_patient, schedule_discharge
+from erpnext.healthcare.doctype.patient_appointment.test_patient_appointment import create_patient
class TestInpatientRecord(unittest.TestCase):
def test_admit_and_discharge(self):
frappe.db.sql("""delete from `tabInpatient Record`""")
- patient = get_patient()
+ patient = create_patient()
# Schedule Admission
ip_record = create_inpatient(patient)
ip_record.save(ignore_permissions = True)
@@ -41,7 +42,7 @@
def test_validate_overlap_admission(self):
frappe.db.sql("""delete from `tabInpatient Record`""")
- patient = get_patient()
+ patient = create_patient()
ip_record = create_inpatient(patient)
ip_record.save(ignore_permissions = True)
@@ -75,17 +76,6 @@
inpatient_record.scheduled_date = today()
return inpatient_record
-def get_patient():
- patient = get_random("Patient")
- if not patient:
- patient = frappe.new_doc("Patient")
- patient.patient_name = "Test Patient"
- patient.sex = "Male"
- patient.save(ignore_permissions=True)
- return patient.name
- return patient
-
-
def get_healthcare_service_unit():
service_unit = get_random("Healthcare Service Unit", filters={"inpatient_occupancy": 1})
if not service_unit:
diff --git a/erpnext/healthcare/doctype/lab_prescription/lab_prescription.json b/erpnext/healthcare/doctype/lab_prescription/lab_prescription.json
index d6691d4..0720bb4 100644
--- a/erpnext/healthcare/doctype/lab_prescription/lab_prescription.json
+++ b/erpnext/healthcare/doctype/lab_prescription/lab_prescription.json
@@ -1,238 +1,78 @@
{
- "allow_copy": 1,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 1,
- "creation": "2016-09-16 16:53:06.882970",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Document",
- "editable_grid": 1,
+ "actions": [],
+ "allow_copy": 1,
+ "beta": 1,
+ "creation": "2016-09-16 16:53:06.882970",
+ "doctype": "DocType",
+ "document_type": "Document",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "lab_test_code",
+ "lab_test_name",
+ "invoiced",
+ "column_break_4",
+ "lab_test_comment",
+ "lab_test_created"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "lab_test_code",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Test Code",
- "length": 0,
- "no_copy": 0,
- "options": "Lab Test Template",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "lab_test_code",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "in_list_view": 1,
+ "label": "Lab Test",
+ "options": "Lab Test Template",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "lab_test_code.lab_test_name",
- "fieldname": "lab_test_name",
- "fieldtype": "Data",
- "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": "Test",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "lab_test_code.lab_test_name",
+ "fieldname": "lab_test_name",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Lab Test Name"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "invoiced",
- "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": "Invoiced",
- "length": 0,
- "no_copy": 1,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "invoiced",
+ "fieldtype": "Check",
+ "label": "Invoiced",
+ "no_copy": 1,
+ "read_only": 1,
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 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,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_4",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "lab_test_comment",
- "fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Comments",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "lab_test_comment",
+ "fieldtype": "Small Text",
+ "ignore_xss_filter": 1,
+ "in_list_view": 1,
+ "label": "Comments"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "lab_test_created",
- "fieldtype": "Check",
- "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": "Test Created",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "default": "0",
+ "fieldname": "lab_test_created",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "label": "Test Created",
+ "no_copy": 1,
+ "print_hide": 1,
+ "report_hide": 1,
+ "search_index": 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": "2018-09-04 09:02:18.592637",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Lab Prescription",
- "name_case": "",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 0,
- "track_seen": 0,
- "track_views": 0
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-02-26 17:03:00.255560",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Lab Prescription",
+ "owner": "Administrator",
+ "permissions": [],
+ "restrict_to_domain": "Healthcare",
+ "sort_field": "modified",
+ "sort_order": "DESC"
}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.js b/erpnext/healthcare/doctype/lab_test/lab_test.js
index b60e70f..5b3f4c7 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test.js
+++ b/erpnext/healthcare/doctype/lab_test/lab_test.js
@@ -29,7 +29,7 @@
get_lab_test_prescribed(frm);
});
}
- if(frm.doc.docstatus==1 && frm.doc.status!='Approved' && frm.doc.status!='Rejected' && frappe.defaults.get_default("require_test_result_approval") && frappe.user.has_role("LabTest Approver")){
+ if(frm.doc.docstatus==1 && frm.doc.status!='Approved' && frm.doc.status!='Rejected' && frappe.defaults.get_default("lab_test_approval_required") && frappe.user.has_role("LabTest Approver")){
frm.add_custom_button(__('Approve'), function() {
status_update(1,frm);
});
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.json b/erpnext/healthcare/doctype/lab_test/lab_test.json
index 00e613a..ccbc24b 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test.json
+++ b/erpnext/healthcare/doctype/lab_test/lab_test.json
@@ -1,1597 +1,478 @@
{
- "allow_copy": 1,
- "allow_guest_to_view": 0,
- "allow_import": 1,
- "allow_rename": 0,
- "autoname": "naming_series:",
- "beta": 1,
- "creation": "2016-03-29 17:34:47.509094",
- "custom": 0,
- "default_print_format": "",
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Document",
- "editable_grid": 0,
+ "actions": [],
+ "allow_copy": 1,
+ "allow_import": 1,
+ "autoname": "naming_series:",
+ "beta": 1,
+ "creation": "2016-03-29 17:34:47.509094",
+ "doctype": "DocType",
+ "document_type": "Document",
+ "engine": "InnoDB",
+ "field_order": [
+ "inpatient_record",
+ "naming_series",
+ "invoiced",
+ "patient",
+ "patient_name",
+ "patient_age",
+ "patient_sex",
+ "practitioner",
+ "email",
+ "mobile",
+ "company",
+ "c_b",
+ "department",
+ "status",
+ "submitted_date",
+ "approved_date",
+ "sample",
+ "result_date",
+ "employee",
+ "employee_name",
+ "employee_designation",
+ "user",
+ "report_preference",
+ "sb_first",
+ "lab_test_name",
+ "column_break_26",
+ "template",
+ "lab_test_group",
+ "sb_normal",
+ "normal_test_items",
+ "sb_special",
+ "special_test_items",
+ "sb_sensitivity",
+ "sensitivity_test_items",
+ "sb_comments",
+ "lab_test_comment",
+ "sb_customresult",
+ "custom_result",
+ "email_sent",
+ "sms_sent",
+ "printed",
+ "normal_toggle",
+ "special_toggle",
+ "sensitivity_toggle",
+ "amended_from",
+ "prescription"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "patient.inpatient_record",
- "fieldname": "inpatient_record",
- "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": "Inpatient Record",
- "length": 0,
- "no_copy": 0,
- "options": "Inpatient Record",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "patient.inpatient_record",
+ "fieldname": "inpatient_record",
+ "fieldtype": "Link",
+ "label": "Inpatient Record",
+ "options": "Inpatient Record",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "naming_series",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Series",
- "length": 0,
- "no_copy": 0,
- "options": "LP-",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "naming_series",
+ "fieldtype": "Select",
+ "label": "Series",
+ "options": "LP-",
+ "print_hide": 1,
+ "report_hide": 1,
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "invoiced",
- "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": "Invoiced",
- "length": 0,
- "no_copy": 1,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "invoiced",
+ "fieldtype": "Check",
+ "label": "Invoiced",
+ "no_copy": 1,
+ "read_only": 1,
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "inpatient_record.patient",
- "fieldname": "patient",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Patient",
- "length": 0,
- "no_copy": 0,
- "options": "Patient",
- "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": 1,
- "set_only_once": 1,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "inpatient_record.patient",
+ "fieldname": "patient",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Patient",
+ "options": "Patient",
+ "reqd": 1,
+ "search_index": 1,
+ "set_only_once": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "patient.patient_name",
- "fieldname": "patient_name",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Patient Name",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "patient.patient_name",
+ "fieldname": "patient_name",
+ "fieldtype": "Data",
+ "label": "Patient Name",
+ "print_hide": 1,
+ "read_only": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "patient_age",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Age",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "patient_age",
+ "fieldtype": "Data",
+ "label": "Age",
+ "print_hide": 1,
+ "read_only": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "patient_sex",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Gender",
- "length": 0,
- "no_copy": 0,
- "options": "\nMale\nFemale\nOther",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 1,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "patient_sex",
+ "fieldtype": "Link",
+ "label": "Gender",
+ "options": "Gender",
+ "print_hide": 1,
+ "report_hide": 1,
+ "reqd": 1,
+ "set_only_once": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "practitioner",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Healthcare Practitioner",
- "length": 0,
- "no_copy": 0,
- "options": "Healthcare Practitioner",
- "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": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "practitioner",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "label": "Healthcare Practitioner",
+ "options": "Healthcare Practitioner",
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "email",
- "fieldtype": "Data",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Email",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "email",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "label": "Email",
+ "print_hide": 1,
+ "read_only": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "mobile",
- "fieldtype": "Data",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Mobile",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "mobile",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "label": "Mobile",
+ "print_hide": 1,
+ "read_only": 1,
+ "report_hide": 1,
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "company",
- "fieldtype": "Link",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Company",
- "length": 0,
- "no_copy": 0,
- "options": "Company",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "label": "Company",
+ "options": "Company",
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "c_b",
- "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": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "c_b",
+ "fieldtype": "Column Break",
+ "print_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "department",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Department",
- "length": 0,
- "no_copy": 0,
- "options": "Medical Department",
- "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": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "department",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "label": "Department",
+ "options": "Medical Department",
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "status",
- "fieldtype": "Select",
- "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": "Status",
- "length": 0,
- "no_copy": 0,
- "options": "Draft\nCompleted\nApproved\nRejected\nCancelled",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "hidden": 1,
+ "label": "Status",
+ "options": "Draft\nCompleted\nApproved\nRejected\nCancelled",
+ "print_hide": 1,
+ "report_hide": 1,
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "submitted_date",
- "fieldtype": "Datetime",
- "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": "Submitted Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "submitted_date",
+ "fieldtype": "Datetime",
+ "hidden": 1,
+ "label": "Submitted Date",
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "approved_date",
- "fieldtype": "Datetime",
- "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": "Approved Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "approved_date",
+ "fieldtype": "Datetime",
+ "hidden": 1,
+ "label": "Approved Date",
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sample",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Sample ID",
- "length": 0,
- "no_copy": 0,
- "options": "Sample Collection",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "sample",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "in_filter": 1,
+ "label": "Sample ID",
+ "options": "Sample Collection",
+ "print_hide": 1,
+ "read_only": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "fieldname": "result_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Result Date",
- "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": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "result_date",
+ "fieldtype": "Date",
+ "label": "Result Date",
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "employee",
- "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": "Lab Technician",
- "length": 0,
- "no_copy": 1,
- "options": "Employee",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "employee",
+ "fieldtype": "Link",
+ "label": "Lab Technician",
+ "no_copy": 1,
+ "options": "Employee",
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "employee.employee_name",
- "fieldname": "employee_name",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Technician Name",
- "length": 0,
- "no_copy": 1,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "employee.employee_name",
+ "fieldname": "employee_name",
+ "fieldtype": "Data",
+ "label": "Technician Name",
+ "no_copy": 1,
+ "print_hide": 1,
+ "read_only": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "employee.designation",
- "fieldname": "employee_designation",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Designation",
- "length": 0,
- "no_copy": 1,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "employee.designation",
+ "fieldname": "employee_designation",
+ "fieldtype": "Data",
+ "label": "Designation",
+ "no_copy": 1,
+ "print_hide": 1,
+ "read_only": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "user",
- "fieldtype": "Link",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "User",
- "length": 0,
- "no_copy": 1,
- "options": "User",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "user",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "label": "User",
+ "no_copy": 1,
+ "options": "User",
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "report_preference",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Report Preference",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "report_preference",
+ "fieldtype": "Data",
+ "label": "Report Preference",
+ "print_hide": 1,
+ "read_only": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sb_first",
- "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,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "sb_first",
+ "fieldtype": "Section Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "lab_test_name",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Test Name",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "lab_test_name",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Test Name",
+ "no_copy": 1,
+ "print_hide": 1,
+ "read_only": 1,
+ "report_hide": 1,
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_26",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_26",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "template",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Test Template",
- "length": 0,
- "no_copy": 0,
- "options": "Lab Test Template",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 1,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "template",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "label": "Test Template",
+ "options": "Lab Test Template",
+ "print_hide": 1,
+ "report_hide": 1,
+ "reqd": 1,
+ "set_only_once": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "lab_test_group",
- "fieldtype": "Link",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Test Group",
- "length": 0,
- "no_copy": 0,
- "options": "Item Group",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "lab_test_group",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "label": "Test Group",
+ "options": "Item Group",
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sb_normal",
- "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,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "sb_normal",
+ "fieldtype": "Section Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "normal_test_items",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "options": "Normal Test Items",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "normal_test_items",
+ "fieldtype": "Table",
+ "options": "Normal Test Items"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sb_special",
- "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,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "sb_special",
+ "fieldtype": "Section Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "special_test_items",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "options": "Special Test Items",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "special_test_items",
+ "fieldtype": "Table",
+ "options": "Special Test Items",
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sb_sensitivity",
- "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,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "sb_sensitivity",
+ "fieldtype": "Section Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sensitivity_test_items",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "options": "Sensitivity Test Items",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "sensitivity_test_items",
+ "fieldtype": "Table",
+ "options": "Sensitivity Test Items",
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sb_comments",
- "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,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "sb_comments",
+ "fieldtype": "Section Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "lab_test_comment",
- "fieldtype": "Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Comments",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "lab_test_comment",
+ "fieldtype": "Text",
+ "ignore_xss_filter": 1,
+ "label": "Comments"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 1,
- "columns": 0,
- "fieldname": "sb_customresult",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Custom Result",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "collapsible": 1,
+ "fieldname": "sb_customresult",
+ "fieldtype": "Section Break",
+ "label": "Custom Result"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "custom_result",
- "fieldtype": "Text Editor",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Custom Result",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "custom_result",
+ "fieldtype": "Text Editor",
+ "ignore_xss_filter": 1,
+ "label": "Custom Result"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "email_sent",
- "fieldtype": "Check",
- "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,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "email_sent",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "sms_sent",
- "fieldtype": "Check",
- "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": "",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "sms_sent",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "printed",
- "fieldtype": "Check",
- "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,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "printed",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "normal_toggle",
- "fieldtype": "Check",
- "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,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "normal_toggle",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "special_toggle",
- "fieldtype": "Check",
- "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,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "special_toggle",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "sensitivity_toggle",
- "fieldtype": "Check",
- "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,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "sensitivity_toggle",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 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": "Lab Test",
- "permlevel": 0,
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "label": "Amended From",
+ "no_copy": 1,
+ "options": "Lab Test",
+ "print_hide": 1,
+ "read_only": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "prescription",
- "fieldtype": "Link",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Prescription",
- "length": 0,
- "no_copy": 1,
- "options": "Lab Prescription",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "fieldname": "prescription",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "label": "Prescription",
+ "no_copy": 1,
+ "options": "Lab Prescription",
+ "print_hide": 1,
+ "read_only": 1,
+ "report_hide": 1
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "icon": "",
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 1,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-09-04 10:19:33.422304",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Lab Test",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "is_submittable": 1,
+ "links": [],
+ "modified": "2020-03-23 19:37:06.617764",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Lab Test",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 1,
- "cancel": 1,
- "create": 1,
- "delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Laboratory User",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 1,
+ "amend": 1,
+ "cancel": 1,
+ "create": 1,
+ "email": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Laboratory User",
+ "share": 1,
+ "submit": 1,
"write": 1
- },
+ },
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "LabTest Approver",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "LabTest Approver",
+ "share": 1,
"write": 1
- },
+ },
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Physician",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Physician",
+ "share": 1,
"write": 1
}
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "search_fields": "patient,practitioner,lab_test_name,sample",
- "show_name_in_global_search": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "patient",
- "track_changes": 1,
- "track_seen": 1,
- "track_views": 0
+ ],
+ "restrict_to_domain": "Healthcare",
+ "search_fields": "patient,practitioner,lab_test_name,sample",
+ "show_name_in_global_search": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "patient",
+ "track_changes": 1,
+ "track_seen": 1
}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.py b/erpnext/healthcare/doctype/lab_test/lab_test.py
index 8609489..4e4015d 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test.py
+++ b/erpnext/healthcare/doctype/lab_test/lab_test.py
@@ -191,20 +191,24 @@
special.template = template.name
def create_sample_doc(template, patient, invoice):
- if(template.sample):
- sample_exist = frappe.db.exists({
+ if template.sample:
+ sample_exists = frappe.db.exists({
"doctype": "Sample Collection",
"patient": patient.name,
"docstatus": 0,
- "sample": template.sample})
- if sample_exist :
- #Update Sample Collection by adding quantity
- sample_collection = frappe.get_doc("Sample Collection",sample_exist[0][0])
- quantity = int(sample_collection.sample_quantity)+int(template.sample_quantity)
- if(template.sample_collection_details):
- sample_collection_details = sample_collection.sample_collection_details+"\n==============\n"+"Test :"+template.lab_test_name+"\n"+"Collection Detials:\n\t"+template.sample_collection_details
- frappe.db.set_value("Sample Collection", sample_collection.name, "sample_collection_details",sample_collection_details)
- frappe.db.set_value("Sample Collection", sample_collection.name, "sample_quantity",quantity)
+ "sample": template.sample
+ })
+ if sample_exists:
+ # update Sample Collection by adding quantity
+ sample_collection = frappe.get_doc("Sample Collection", sample_exists[0][0])
+ quantity = int(sample_collection.sample_qty) + int(template.sample_qty)
+ if template.sample_details:
+ sample_details = sample_collection.sample_details + "\n==============\n" + _("Test: ")
+ sample_details += (template.get("lab_test_name") or template.get("template")) + "\n"
+ sample_details += _("Collection Details: ") + "\n\t" + template.sample_details
+
+ frappe.db.set_value("Sample Collection", sample_collection.name, "sample_details", sample_details)
+ frappe.db.set_value("Sample Collection", sample_collection.name, "sample_qty", quantity)
else:
#create Sample Collection for template, copy vals from Invoice
@@ -216,15 +220,15 @@
sample_collection.patient_sex = patient.sex
sample_collection.sample = template.sample
sample_collection.sample_uom = template.sample_uom
- sample_collection.sample_quantity = template.sample_quantity
- if(template.sample_collection_details):
- sample_collection.sample_collection_details = "Test :"+template.lab_test_name+"\n"+"Collection Detials:\n\t"+template.sample_collection_details
+ sample_collection.sample_qty = template.sample_qty
+ if(template.sample_details):
+ sample_collection.sample_details = "Test :" + (template.get("lab_test_name") or template.get("template")) +"\n"+"Collection Detials:\n\t"+template.sample_details
sample_collection.save(ignore_permissions=True)
return sample_collection
def create_sample_collection(lab_test, template, patient, invoice):
- if(frappe.db.get_value("Healthcare Settings", None, "require_sample_collection") == "1"):
+ if(frappe.db.get_value("Healthcare Settings", None, "create_sample_collection_for_lab_test") == "1"):
sample_collection = create_sample_doc(template, patient, invoice)
if(sample_collection):
lab_test.sample = sample_collection.name
@@ -290,10 +294,14 @@
comment = ""
if item.lab_test_comment:
comment = str(item.lab_test_comment)
- event = ""
+ table_row = item.lab_test_name
+
if item.lab_test_event:
- event = item.lab_test_event
- table_row = item.lab_test_name +" "+ event +" "+ item.result_value
+ table_row += " " + item.lab_test_event
+
+ if item.result_value:
+ table_row += " " + item.result_value
+
if item.normal_range:
table_row += " normal_range("+item.normal_range+")"
table_row += " "+comment
diff --git a/erpnext/healthcare/doctype/lab_test_sample/lab_test_sample.json b/erpnext/healthcare/doctype/lab_test_sample/lab_test_sample.json
index 46c04c6..2830038 100644
--- a/erpnext/healthcare/doctype/lab_test_sample/lab_test_sample.json
+++ b/erpnext/healthcare/doctype/lab_test_sample/lab_test_sample.json
@@ -1,145 +1,68 @@
{
- "allow_copy": 1,
- "allow_guest_to_view": 0,
- "allow_import": 1,
- "allow_rename": 1,
- "autoname": "field:sample",
- "beta": 1,
- "creation": "2016-04-04 17:35:44.823951",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 0,
+ "actions": [],
+ "allow_copy": 1,
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "field:sample",
+ "beta": 1,
+ "creation": "2016-04-04 17:35:44.823951",
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "engine": "InnoDB",
+ "field_order": [
+ "sample",
+ "sample_uom"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sample",
- "fieldtype": "Data",
- "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": "Sample",
- "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
- },
+ "fieldname": "sample",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Sample",
+ "reqd": 1,
+ "unique": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 1,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sample_uom",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "UOM",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
+ "bold": 1,
+ "fieldname": "sample_uom",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "UOM",
+ "options": "Lab Test UOM"
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2017-08-31 13:46:22.508908",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Lab Test Sample",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "links": [],
+ "modified": "2020-01-29 23:02:02.249839",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Lab Test Sample",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 0,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Healthcare Administrator",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Healthcare Administrator",
+ "share": 1,
"write": 1
- },
+ },
{
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Laboratory User",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 0
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Laboratory User",
+ "share": 1
}
- ],
- "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "sample",
- "track_changes": 1,
- "track_seen": 0
+ ],
+ "quick_entry": 1,
+ "restrict_to_domain": "Healthcare",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "sample",
+ "track_changes": 1
}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.json b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.json
index fcfecba..a606bc4 100644
--- a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.json
+++ b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.json
@@ -35,8 +35,8 @@
"sb_sample_collection",
"sample",
"sample_uom",
- "sample_quantity",
- "sample_collection_details",
+ "sample_qty",
+ "sample_details",
"change_in_item"
],
"fields": [
@@ -105,7 +105,7 @@
"description": "If unchecked, the item wont be appear in Sales Invoice, but can be used in group test creation. ",
"fieldname": "is_billable",
"fieldtype": "Check",
- "label": "Is billable",
+ "label": "Is Billable",
"search_index": 1
},
{
@@ -114,7 +114,8 @@
"fieldname": "lab_test_rate",
"fieldtype": "Currency",
"in_list_view": 1,
- "label": "Standard Selling Rate"
+ "label": "Rate",
+ "mandatory_depends_on": "eval:doc.is_billable == 1"
},
{
"depends_on": "eval:doc.lab_test_template_type == 'Single'",
@@ -211,18 +212,6 @@
},
{
"default": "0",
- "fieldname": "sample_quantity",
- "fieldtype": "Float",
- "label": "Quantity"
- },
- {
- "fieldname": "sample_collection_details",
- "fieldtype": "Text",
- "ignore_xss_filter": 1,
- "label": "Collection Details"
- },
- {
- "default": "0",
"fieldname": "change_in_item",
"fieldtype": "Check",
"hidden": 1,
@@ -236,11 +225,23 @@
"fieldname": "disabled",
"fieldtype": "Check",
"label": "Disabled"
+ },
+ {
+ "default": "0",
+ "fieldname": "sample_qty",
+ "fieldtype": "Float",
+ "label": "Quantity"
+ },
+ {
+ "fieldname": "sample_details",
+ "fieldtype": "Text",
+ "ignore_xss_filter": 1,
+ "label": "Collection Details"
}
],
"links": [],
- "modified": "2020-01-21 21:02:16.108347",
- "modified_by": "ruchamahabal2@gmail.com",
+ "modified": "2020-03-25 16:53:01.740103",
+ "modified_by": "Administrator",
"module": "Healthcare",
"name": "Lab Test Template",
"owner": "Administrator",
diff --git a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py
index fd7ae80..6bbb4f1 100644
--- a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py
+++ b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py
@@ -99,13 +99,10 @@
# get item price list to insert item price
if doc.lab_test_rate != 0.0:
price_list_name = frappe.db.get_value("Price List", {"selling": 1})
- if(doc.lab_test_rate):
+ if doc.lab_test_rate:
make_item_price(item.name, price_list_name, doc.lab_test_rate)
- item.standard_rate = doc.lab_test_rate
else:
make_item_price(item.name, price_list_name, 0.0)
- item.standard_rate = 0.0
- item.save(ignore_permissions = True)
# Set item in the template
frappe.db.set_value("Lab Test Template", doc.name, "item", item.name)
diff --git a/erpnext/healthcare/doctype/patient/patient.js b/erpnext/healthcare/doctype/patient/patient.js
index 1a34fe8..d5df956 100644
--- a/erpnext/healthcare/doctype/patient/patient.js
+++ b/erpnext/healthcare/doctype/patient/patient.js
@@ -3,128 +3,77 @@
frappe.ui.form.on('Patient', {
refresh: function (frm) {
- frm.set_query("patient", "patient_relation", function () {
+ frm.set_query('patient', 'patient_relation', function () {
return {
filters: [
- ["Patient", "name", "!=", frm.doc.name]
+ ['Patient', 'name', '!=', frm.doc.name]
]
};
});
- if (frappe.defaults.get_default("patient_master_name") != "Naming Series") {
- frm.toggle_display("naming_series", false);
+
+ if (frappe.defaults.get_default('patient_name_by') != 'Naming Series') {
+ frm.toggle_display('naming_series', false);
} else {
erpnext.toggle_naming_series();
}
- if (frappe.defaults.get_default("collect_registration_fee") && frm.doc.disabled == 1) {
+
+ if (frappe.defaults.get_default('collect_registration_fee') && frm.doc.status == 'Disabled') {
frm.add_custom_button(__('Invoice Patient Registration'), function () {
- btn_invoice_registration(frm);
+ invoice_registration(frm);
});
}
- if (frm.doc.patient_name && frappe.user.has_role("Physician")) {
- frm.add_custom_button(__('Patient History'), function () {
- frappe.route_options = { "patient": frm.doc.name };
- frappe.set_route("patient_history");
- },"View");
+
+ if (frm.doc.patient_name && frappe.user.has_role('Physician')) {
+ frm.add_custom_button(__('Patient History'), function() {
+ frappe.route_options = {'patient': frm.doc.name};
+ frappe.set_route('patient_history');
+ },'View');
}
- if (!frm.doc.__islocal && (frappe.user.has_role("Nursing User") || frappe.user.has_role("Physician"))) {
+
+ if (!frm.doc.__islocal && (frappe.user.has_role('Nursing User') || frappe.user.has_role('Physician'))) {
frm.add_custom_button(__('Vital Signs'), function () {
- btn_create_vital_signs(frm);
- }, "Create");
+ create_vital_signs(frm);
+ }, 'Create');
frm.add_custom_button(__('Medical Record'), function () {
create_medical_record(frm);
- }, "Create");
+ }, 'Create');
frm.add_custom_button(__('Patient Encounter'), function () {
- btn_create_encounter(frm);
- }, "Create");
+ create_encounter(frm);
+ }, 'Create');
}
},
onload: function (frm) {
if(!frm.doc.dob){
- $(frm.fields_dict['age_html'].wrapper).html("");
+ $(frm.fields_dict['age_html'].wrapper).html('');
}
if(frm.doc.dob){
- $(frm.fields_dict['age_html'].wrapper).html("AGE : " + get_age(frm.doc.dob));
+ $(frm.fields_dict['age_html'].wrapper).html('AGE : ' + get_age(frm.doc.dob));
}
}
});
-frappe.ui.form.on("Patient", "dob", function(frm) {
- if(frm.doc.dob) {
- var today = new Date();
- var birthDate = new Date(frm.doc.dob);
- if(today < birthDate){
- frappe.msgprint(__("Please select a valid Date"));
- frappe.model.set_value(frm.doctype,frm.docname, "dob", "");
+frappe.ui.form.on('Patient', 'dob', function(frm) {
+ if (frm.doc.dob) {
+ let today = new Date();
+ let birthDate = new Date(frm.doc.dob);
+ if (today < birthDate){
+ frappe.msgprint(__('Please select a valid Date'));
+ frappe.model.set_value(frm.doctype,frm.docname, 'dob', '');
}
- else{
- var age_str = get_age(frm.doc.dob);
- $(frm.fields_dict['age_html'].wrapper).html("AGE : " + age_str);
+ else {
+ let age_str = get_age(frm.doc.dob);
+ $(frm.fields_dict['age_html'].wrapper).html('AGE : ' + age_str);
}
}
else {
- $(frm.fields_dict['age_html'].wrapper).html("");
+ $(frm.fields_dict['age_html'].wrapper).html('');
}
});
-var create_medical_record = function (frm) {
- frappe.route_options = {
- "patient": frm.doc.name,
- "status": "Open",
- "reference_doctype": "Patient Medical Record",
- "reference_owner": frm.doc.owner
- };
- frappe.new_doc("Patient Medical Record");
-};
-
-var get_age = function (birth) {
- var ageMS = Date.parse(Date()) - Date.parse(birth);
- var age = new Date();
- age.setTime(ageMS);
- var years = age.getFullYear() - 1970;
- return years + " Year(s) " + age.getMonth() + " Month(s) " + age.getDate() + " Day(s)";
-};
-
-var btn_create_vital_signs = function (frm) {
- if (!frm.doc.name) {
- frappe.throw(__("Please save the patient first"));
- }
- frappe.route_options = {
- "patient": frm.doc.name,
- };
- frappe.new_doc("Vital Signs");
-};
-
-var btn_create_encounter = function (frm) {
- if (!frm.doc.name) {
- frappe.throw(__("Please save the patient first"));
- }
- frappe.route_options = {
- "patient": frm.doc.name,
- };
- frappe.new_doc("Patient Encounter");
-};
-
-var btn_invoice_registration = function (frm) {
- frappe.call({
- doc: frm.doc,
- method: "invoice_patient_registration",
- callback: function(data){
- if(!data.exc){
- if(data.message.invoice){
- /* frappe.show_alert(__('Sales Invoice {0} created',
- ['<a href="#Form/Sales Invoice/'+data.message.invoice+'">' + data.message.invoice+ '</a>'])); */
- frappe.set_route("Form", "Sales Invoice", data.message.invoice);
- }
- cur_frm.reload_doc();
- }
- }
- });
-};
-
frappe.ui.form.on('Patient Relation', {
patient_relation_add: function(frm){
frm.fields_dict['patient_relation'].grid.get_field('patient').get_query = function(doc){
- var patient_list = [];
+ let patient_list = [];
if(!doc.__islocal) patient_list.push(doc.name);
$.each(doc.patient_relation, function(idx, val){
if (val.patient) patient_list.push(val.patient);
@@ -133,3 +82,56 @@
};
}
});
+
+let create_medical_record = function (frm) {
+ frappe.route_options = {
+ 'patient': frm.doc.name,
+ 'status': 'Open',
+ 'reference_doctype': 'Patient Medical Record',
+ 'reference_owner': frm.doc.owner
+ };
+ frappe.new_doc('Patient Medical Record');
+};
+
+let get_age = function (birth) {
+ let ageMS = Date.parse(Date()) - Date.parse(birth);
+ let age = new Date();
+ age.setTime(ageMS);
+ let years = age.getFullYear() - 1970;
+ return years + ' Year(s) ' + age.getMonth() + ' Month(s) ' + age.getDate() + ' Day(s)';
+};
+
+let create_vital_signs = function (frm) {
+ if (!frm.doc.name) {
+ frappe.throw(__('Please save the patient first'));
+ }
+ frappe.route_options = {
+ 'patient': frm.doc.name,
+ };
+ frappe.new_doc('Vital Signs');
+};
+
+let create_encounter = function (frm) {
+ if (!frm.doc.name) {
+ frappe.throw(__('Please save the patient first'));
+ }
+ frappe.route_options = {
+ 'patient': frm.doc.name,
+ };
+ frappe.new_doc('Patient Encounter');
+};
+
+let invoice_registration = function (frm) {
+ frappe.call({
+ doc: frm.doc,
+ method: 'invoice_patient_registration',
+ callback: function(data) {
+ if (!data.exc) {
+ if (data.message.invoice) {
+ frappe.set_route('Form', 'Sales Invoice', data.message.invoice);
+ }
+ cur_frm.reload_doc();
+ }
+ }
+ });
+};
diff --git a/erpnext/healthcare/doctype/patient/patient.json b/erpnext/healthcare/doctype/patient/patient.json
index 0136f72..4258e40 100644
--- a/erpnext/healthcare/doctype/patient/patient.json
+++ b/erpnext/healthcare/doctype/patient/patient.json
@@ -1,4 +1,5 @@
{
+ "actions": [],
"allow_copy": 1,
"allow_import": 1,
"allow_rename": 1,
@@ -11,23 +12,29 @@
"engine": "InnoDB",
"field_order": [
"basic_info",
- "inpatient_status",
- "inpatient_record",
"naming_series",
+ "first_name",
+ "middle_name",
+ "last_name",
"patient_name",
"sex",
"blood_group",
"dob",
"age_html",
- "status",
"image",
"column_break_14",
+ "status",
+ "inpatient_status",
+ "inpatient_record",
"customer",
- "report_preference",
"mobile",
"email",
"phone",
- "disabled",
+ "report_preference",
+ "personal_and_social_history",
+ "occupation",
+ "column_break_25",
+ "marital_status",
"sb_relation",
"patient_relation",
"allergy_medical_and_surgical_history",
@@ -36,10 +43,6 @@
"column_break_20",
"medical_history",
"surgical_history",
- "personal_and_social_history",
- "occupation",
- "column_break_25",
- "marital_status",
"risk_factors",
"tobacco_past_use",
"tobacco_current_use",
@@ -78,28 +81,28 @@
{
"fieldname": "naming_series",
"fieldtype": "Select",
- "label": "Patient ID",
+ "label": "Series",
"options": "HLC-PAT-.YYYY.-",
"print_hide": 1,
- "report_hide": 1
+ "report_hide": 1,
+ "set_only_once": 1
},
{
"bold": 1,
"fieldname": "patient_name",
"fieldtype": "Data",
- "in_filter": 1,
+ "in_global_search": 1,
+ "in_list_view": 1,
"in_standard_filter": 1,
"label": "Full Name",
- "no_copy": 1,
- "oldfieldtype": "Data",
- "reqd": 1,
+ "read_only": 1,
"search_index": 1
},
{
"fieldname": "sex",
- "fieldtype": "Select",
+ "fieldtype": "Link",
"label": "Gender",
- "options": "\nMale\nFemale\nOther",
+ "options": "Gender",
"reqd": 1
},
{
@@ -125,15 +128,15 @@
"report_hide": 1
},
{
- "default": "Active",
"fieldname": "status",
"fieldtype": "Select",
- "hidden": 1,
+ "in_filter": 1,
+ "in_list_view": 1,
"label": "Status",
"no_copy": 1,
- "options": "Active\nDormant\nOpen",
+ "options": "Active\nDisabled",
"print_hide": 1,
- "report_hide": 1
+ "read_only": 1
},
{
"fieldname": "image",
@@ -149,12 +152,12 @@
"fieldtype": "Column Break"
},
{
+ "description": "If \"Link Customer to Patient\" is checked in Healthcare Settings and an existing Customer is not selected then, a Customer will be created for this Patient for recording transactions in Accounts module.",
"fieldname": "customer",
"fieldtype": "Link",
"ignore_user_permissions": 1,
"label": "Customer",
- "options": "Customer",
- "set_only_once": 1
+ "options": "Customer"
},
{
"fieldname": "report_preference",
@@ -183,20 +186,9 @@
"fieldname": "phone",
"fieldtype": "Data",
"in_filter": 1,
- "in_list_view": 1,
"label": "Phone"
},
{
- "default": "0",
- "fieldname": "disabled",
- "fieldtype": "Check",
- "hidden": 1,
- "label": "Disabled",
- "no_copy": 1,
- "print_hide": 1,
- "report_hide": 1
- },
- {
"collapsible": 1,
"fieldname": "sb_relation",
"fieldtype": "Section Break",
@@ -276,25 +268,25 @@
"fieldname": "tobacco_past_use",
"fieldtype": "Data",
"ignore_xss_filter": 1,
- "label": "Tobacco Past Use"
+ "label": "Tobacco Consumption Habbits (Past)"
},
{
"fieldname": "tobacco_current_use",
"fieldtype": "Data",
"ignore_xss_filter": 1,
- "label": "Tobacco Current Use"
+ "label": "Tobacco Consumption Habbits (Present)"
},
{
"fieldname": "alcohol_past_use",
"fieldtype": "Data",
"ignore_xss_filter": 1,
- "label": "Alcohol Past Use"
+ "label": "Alcohol Consumption Habbits (Past)"
},
{
"fieldname": "alcohol_current_use",
"fieldtype": "Data",
"ignore_user_permissions": 1,
- "label": "Alcohol Current Use"
+ "label": "Alcohol Consumption Habbits (Present)"
},
{
"fieldname": "column_break_32",
@@ -342,12 +334,30 @@
"label": "Default Currency",
"options": "Currency",
"print_hide": 1
+ },
+ {
+ "fieldname": "last_name",
+ "fieldtype": "Data",
+ "label": "Last Name"
+ },
+ {
+ "fieldname": "first_name",
+ "fieldtype": "Data",
+ "label": "First Name",
+ "oldfieldtype": "Data",
+ "reqd": 1
+ },
+ {
+ "fieldname": "middle_name",
+ "fieldtype": "Data",
+ "label": "Middle Name (optional)"
}
],
"icon": "fa fa-user",
"image_field": "image",
+ "links": [],
"max_attachments": 50,
- "modified": "2019-09-25 23:30:49.905893",
+ "modified": "2020-04-06 12:55:30.807744",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Patient",
diff --git a/erpnext/healthcare/doctype/patient/patient.py b/erpnext/healthcare/doctype/patient/patient.py
index e3eea96..e304a0b 100644
--- a/erpnext/healthcare/doctype/patient/patient.py
+++ b/erpnext/healthcare/doctype/patient/patient.py
@@ -6,46 +6,57 @@
import frappe
from frappe import _
from frappe.model.document import Document
-from frappe.utils import cint, cstr, getdate, flt
+from frappe.utils import cint, cstr, getdate
import dateutil
from frappe.model.naming import set_name_by_naming_series
-from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account,get_income_account,send_registration_sms
+from frappe.utils.nestedset import get_root_of
+from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account, get_income_account, send_registration_sms
class Patient(Document):
- def after_insert(self):
- if(frappe.db.get_value("Healthcare Settings", None, "manage_customer") == '1' and not self.customer):
- create_customer(self)
- if(frappe.db.get_value("Healthcare Settings", None, "collect_registration_fee") == '1'):
- frappe.db.set_value("Patient", self.name, "disabled", 1)
- else:
- send_registration_sms(self)
- self.reload()
-
- def on_update(self):
+ def validate(self):
+ self.set_full_name()
self.add_as_website_user()
+ def after_insert(self):
+ self.add_as_website_user()
+ self.reload()
+ if frappe.db.get_single_value('Healthcare Settings', 'link_customer_to_patient') and not self.customer:
+ create_customer(self)
+ if frappe.db.get_single_value('Healthcare Settings', 'collect_registration_fee'):
+ frappe.db.set_value('Patient', self.name, 'status', 'Disabled')
+ else:
+ send_registration_sms(self)
+
+ def set_full_name(self):
+ if self.last_name:
+ self.patient_name = ' '.join(filter(None, [self.first_name, self.last_name]))
+ else:
+ self.patient_name = self.first_name
+
def add_as_website_user(self):
- if(self.email):
- if not frappe.db.exists ("User", self.email):
+ if self.email:
+ if not frappe.db.exists ('User', self.email):
user = frappe.get_doc({
- "doctype": "User",
- "first_name": self.patient_name,
- "email": self.email,
- "user_type": "Website User"
+ 'doctype': 'User',
+ 'first_name': self.first_name,
+ 'last_name': self.last_name,
+ 'email': self.email,
+ 'user_type': 'Website User'
})
user.flags.ignore_permissions = True
- user.add_roles("Patient")
+ user.add_roles('Patient')
def autoname(self):
- patient_master_name = frappe.defaults.get_global_default('patient_master_name')
- if patient_master_name == 'Patient Name':
+ patient_name_by = frappe.db.get_single_value('Healthcare Settings', 'patient_name_by')
+ if patient_name_by == 'Patient Name':
self.name = self.get_patient_name()
else:
set_name_by_naming_series(self)
def get_patient_name(self):
+ self.set_full_name()
name = self.patient_name
- if frappe.db.get_value("Patient", name):
+ if frappe.db.get_value('Patient', name):
count = frappe.db.sql("""select ifnull(MAX(CAST(SUBSTRING_INDEX(name, ' ', -1) AS UNSIGNED)), 0) from tabPatient
where name like %s""", "%{0} - %".format(name), as_list=1)[0][0]
count = cint(count) + 1
@@ -54,56 +65,62 @@
return name
def get_age(self):
- age_str = ""
+ age_str = ''
if self.dob:
- born = getdate(self.dob)
- age = dateutil.relativedelta.relativedelta(getdate(), born)
- age_str = str(age.years) + " year(s) " + str(age.months) + " month(s) " + str(age.days) + " day(s)"
+ dob = getdate(self.dob)
+ age = dateutil.relativedelta.relativedelta(getdate(), dob)
+ age_str = str(age.years) + ' year(s) ' + str(age.months) + ' month(s) ' + str(age.days) + ' day(s)'
return age_str
def invoice_patient_registration(self):
- frappe.db.set_value("Patient", self.name, "disabled", 0)
- send_registration_sms(self)
- if(flt(frappe.get_value("Healthcare Settings", None, "registration_fee"))>0):
+ if frappe.db.get_single_value('Healthcare Settings', 'registration_fee'):
company = frappe.defaults.get_user_default('company')
if not company:
- company = frappe.db.get_value("Global Defaults", None, "default_company")
+ company = frappe.db.get_single_value('Global Defaults', 'default_company')
+
sales_invoice = make_invoice(self.name, company)
sales_invoice.save(ignore_permissions=True)
+ frappe.db.set_value('Patient', self.name, 'status', 'Active')
+ send_registration_sms(self)
+
return {'invoice': sales_invoice.name}
def create_customer(doc):
- customer_group = frappe.get_value("Selling Settings", None, "customer_group")
- territory = frappe.get_value("Selling Settings", None, "territory")
+ customer_group = frappe.db.get_single_value('Selling Settings', 'customer_group')
+ territory = frappe.db.get_single_value('Selling Settings', 'territory')
if not (customer_group and territory):
- customer_group = "Commercial"
- territory = "Rest Of The World"
- frappe.msgprint(_("Please set default customer group and territory in Selling Settings"), alert=True)
- customer = frappe.get_doc({"doctype": "Customer",
- "customer_name": doc.patient_name,
- "customer_group": customer_group,
- "territory" : territory,
- "customer_type": "Individual"
- }).insert(ignore_permissions=True)
- frappe.db.set_value("Patient", doc.name, "customer", customer.name)
- frappe.msgprint(_("Customer {0} is created.").format(customer.name), alert=True)
+ customer_group = get_root_of('Customer Group')
+ territory = get_root_of('Territory')
+ frappe.msgprint(_('Please set default customer group and territory in Selling Settings'), alert=True)
+
+ customer = frappe.get_doc({
+ 'doctype': 'Customer',
+ 'customer_name': doc.patient_name,
+ 'customer_group': customer_group,
+ 'territory' : territory,
+ 'customer_type': 'Individual'
+ }).insert(ignore_permissions=True, ignore_mandatory=True)
+
+ frappe.db.set_value('Patient', doc.name, 'customer', customer.name)
+ frappe.msgprint(_('Customer {0} is created.').format(customer.name), alert=True)
def make_invoice(patient, company):
- sales_invoice = frappe.new_doc("Sales Invoice")
- sales_invoice.customer = frappe.get_value("Patient", patient, "customer")
+ uom = frappe.db.exists('UOM', 'Nos') or frappe.db.get_single_value('Stock Settings', 'stock_uom')
+ sales_invoice = frappe.new_doc('Sales Invoice')
+ sales_invoice.customer = frappe.db.get_value('Patient', patient, 'customer')
sales_invoice.due_date = getdate()
sales_invoice.company = company
- sales_invoice.is_pos = '0'
+ sales_invoice.is_pos = 0
sales_invoice.debit_to = get_receivable_account(company)
- item_line = sales_invoice.append("items")
- item_line.item_name = "Registeration Fee"
- item_line.description = "Registeration Fee"
+ item_line = sales_invoice.append('items')
+ item_line.item_name = 'Registeration Fee'
+ item_line.description = 'Registeration Fee'
item_line.qty = 1
- item_line.uom = "Nos"
+ item_line.uom = uom
item_line.conversion_factor = 1
item_line.income_account = get_income_account(None, company)
- item_line.rate = frappe.get_value("Healthcare Settings", None, "registration_fee")
+ item_line.rate = frappe.db.get_single_value('Healthcare Settings', 'registration_fee')
item_line.amount = item_line.rate
sales_invoice.set_missing_values()
return sales_invoice
@@ -112,7 +129,7 @@
def get_patient_detail(patient):
patient_dict = frappe.db.sql("""select * from tabPatient where name=%s""", (patient), as_dict=1)
if not patient_dict:
- frappe.throw(_("Patient not found"))
+ frappe.throw(_('Patient not found'))
vital_sign = frappe.db.sql("""select * from `tabVital Signs` where patient=%s
order by signs_date desc limit 1""", (patient), as_dict=1)
diff --git a/erpnext/healthcare/doctype/patient/test_patient.py b/erpnext/healthcare/doctype/patient/test_patient.py
index aebaa6b..9274b6f 100644
--- a/erpnext/healthcare/doctype/patient/test_patient.py
+++ b/erpnext/healthcare/doctype/patient/test_patient.py
@@ -4,8 +4,31 @@
from __future__ import unicode_literals
import unittest
-
-# test_records = frappe.get_test_records('Patient')
+import frappe
+from erpnext.healthcare.doctype.patient_appointment.test_patient_appointment import create_patient
class TestPatient(unittest.TestCase):
- pass
+ def test_customer_created(self):
+ frappe.db.sql("""delete from `tabPatient`""")
+ frappe.db.set_value('Healthcare Settings', None, 'link_customer_to_patient', 1)
+ patient = create_patient()
+ self.assertTrue(frappe.db.get_value('Patient', patient, 'customer'))
+
+ def test_patient_registration(self):
+ frappe.db.sql("""delete from `tabPatient`""")
+ settings = frappe.get_single('Healthcare Settings')
+ settings.collect_registration_fee = 1
+ settings.registration_fee = 500
+ settings.save()
+
+ patient = create_patient()
+ patient = frappe.get_doc('Patient', patient)
+ self.assertEqual(patient.status, 'Disabled')
+
+ # check sales invoice and patient status
+ result = patient.invoice_patient_registration()
+ self.assertTrue(frappe.db.exists('Sales Invoice', result.get('invoice')))
+ self.assertTrue(patient.status, 'Active')
+
+ settings.collect_registration_fee = 0
+ settings.save()
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
index 858145e..efa6b24 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
@@ -1,6 +1,6 @@
// Copyright (c) 2016, ESS LLP and contributors
// For license information, please see license.txt
-frappe.provide("erpnext.queries");
+frappe.provide('erpnext.queries');
frappe.ui.form.on('Patient Appointment', {
setup: function(frm) {
frm.custom_make_buttons = {
@@ -8,151 +8,188 @@
'Patient Encounter': 'Patient Encounter'
};
},
+
+ onload: function(frm) {
+ if (frm.is_new()) {
+ frm.set_value('appointment_time', null);
+ frm.disable_save();
+ }
+ },
+
refresh: function(frm) {
- frm.set_query("patient", function () {
+ frm.set_query('patient', function () {
return {
- filters: {"disabled": 0}
+ filters: {'status': 'Active'}
};
});
- frm.set_query("practitioner", function() {
+ frm.set_query('practitioner', function() {
return {
filters: {
'department': frm.doc.department
}
};
});
- frm.set_query("service_unit", function(){
+ frm.set_query('service_unit', function(){
return {
filters: {
- "is_group": false,
- "allow_appointments": true
+ 'is_group': 0,
+ 'allow_appointments': 1
}
};
});
- if(frm.doc.patient){
+
+ if (frm.is_new()) {
+ frm.page.set_primary_action(__('Check Availability'), function() {
+ if (!frm.doc.patient) {
+ frappe.msgprint({
+ title: __('Not Allowed'),
+ message: __('Please select Patient first'),
+ indicator: 'red'
+ });
+ } else {
+ frappe.call({
+ method: 'erpnext.healthcare.doctype.patient_appointment.patient_appointment.check_payment_fields_reqd',
+ args: {'patient': frm.doc.patient},
+ callback: function(data) {
+ if (data.message == true) {
+ if (frm.doc.mode_of_payment && frm.doc.paid_amount) {
+ check_and_set_availability(frm);
+ }
+ if (!frm.doc.mode_of_payment) {
+ frappe.msgprint({
+ title: __('Not Allowed'),
+ message: __('Please select a Mode of Payment first'),
+ indicator: 'red'
+ });
+ }
+ if (!frm.doc.paid_amount) {
+ frappe.msgprint({
+ title: __('Not Allowed'),
+ message: __('Please set the Paid Amount first'),
+ indicator: 'red'
+ });
+ }
+ } else {
+ check_and_set_availability(frm);
+ }
+ }
+ });
+ }
+ });
+ } else {
+ frm.page.set_primary_action(__('Save'), () => frm.save());
+ }
+
+ if (frm.doc.patient) {
frm.add_custom_button(__('Patient History'), function() {
- frappe.route_options = {"patient": frm.doc.patient};
- frappe.set_route("patient_history");
- },__("View"));
+ frappe.route_options = {'patient': frm.doc.patient};
+ frappe.set_route('patient_history');
+ }, __('View'));
}
- if(frm.doc.status == "Open"){
+
+ if (frm.doc.status == 'Open' || (frm.doc.status == 'Scheduled' && !frm.doc.__islocal)) {
frm.add_custom_button(__('Cancel'), function() {
- btn_update_status(frm, "Cancelled");
+ update_status(frm, 'Cancelled');
});
frm.add_custom_button(__('Reschedule'), function() {
check_and_set_availability(frm);
});
- if(frm.doc.procedure_template){
- frm.add_custom_button(__("Procedure"),function(){
- btn_create_procedure(frm);
- },"Create");
- }
- else{
- frm.add_custom_button(__("Patient Encounter"),function(){
- btn_create_encounter(frm);
- },"Create");
+
+ if (frm.doc.procedure_template) {
+ frm.add_custom_button(__('Clinical Procedure'), function(){
+ frappe.model.open_mapped_doc({
+ method: 'erpnext.healthcare.doctype.clinical_procedure.clinical_procedure.make_procedure',
+ frm: frm,
+ });
+ }, __('Create'));
+ } else {
+ frm.add_custom_button(__('Patient Encounter'), function() {
+ frappe.model.open_mapped_doc({
+ method: 'erpnext.healthcare.doctype.patient_appointment.patient_appointment.make_encounter',
+ frm: frm,
+ });
+ }, __('Create'));
}
frm.add_custom_button(__('Vital Signs'), function() {
- btn_create_vital_signs(frm);
- },"Create");
+ create_vital_signs(frm);
+ }, __('Create'));
}
- if(frm.doc.status == "Scheduled" && !frm.doc.__islocal){
- frm.add_custom_button(__('Cancel'), function() {
- btn_update_status(frm, "Cancelled");
- });
- frm.add_custom_button(__('Reschedule'), function() {
- check_and_set_availability(frm);
- });
- if(frm.doc.procedure_template){
- frm.add_custom_button(__("Procedure"),function(){
- btn_create_procedure(frm);
- },"Create");
- }
- else{
- frm.add_custom_button(__("Patient Encounter"),function(){
- btn_create_encounter(frm);
- },"Create");
- }
+ },
- frm.add_custom_button(__('Vital Signs'), function() {
- btn_create_vital_signs(frm);
- },"Create");
+ patient: function(frm) {
+ if (frm.doc.patient) {
+ frm.trigger('toggle_payment_fields');
}
- if(frm.doc.status == "Pending"){
- frm.add_custom_button(__('Set Open'), function() {
- btn_update_status(frm, "Open");
- });
- frm.add_custom_button(__('Cancel'), function() {
- btn_update_status(frm, "Cancelled");
- });
- }
- frm.set_df_property("get_procedure_from_encounter", "read_only", frm.doc.__islocal ? 0 : 1);
- frappe.db.get_value('Healthcare Settings', {name: 'Healthcare Settings'}, 'manage_appointment_invoice_automatically', (r) => {
- if(r.manage_appointment_invoice_automatically == 1){
- frm.set_df_property("mode_of_payment", "hidden", 0);
- frm.set_df_property("paid_amount", "hidden", 0);
- frm.set_df_property("mode_of_payment", "reqd", 1);
- frm.set_df_property("paid_amount", "reqd", 1);
- }
- else{
- frm.set_df_property("mode_of_payment", "hidden", 1);
- frm.set_df_property("paid_amount", "hidden", 1);
- frm.set_df_property("mode_of_payment", "reqd", 0);
- frm.set_df_property("paid_amount", "reqd", 0);
+ },
+
+ get_procedure_from_encounter: function(frm) {
+ get_prescribed_procedure(frm);
+ },
+
+ toggle_payment_fields: function(frm) {
+ frappe.call({
+ method: 'erpnext.healthcare.doctype.patient_appointment.patient_appointment.check_payment_fields_reqd',
+ args: {'patient': frm.doc.patient},
+ callback: function(data) {
+ if (data.message.fee_validity) {
+ // if fee validity exists and automated appointment invoicing is enabled,
+ // show payment fields as non-mandatory
+ frm.toggle_display('mode_of_payment', 0);
+ frm.toggle_display('paid_amount', 0);
+ frm.toggle_reqd('mode_of_payment', 0);
+ frm.toggle_reqd('paid_amount', 0);
+ } else {
+ // if automated appointment invoicing is disabled, hide fields
+ frm.toggle_display('mode_of_payment', data.message ? 1 : 0);
+ frm.toggle_display('paid_amount', data.message ? 1 : 0);
+ frm.toggle_reqd('mode_of_payment', data.message ? 1 : 0);
+ frm.toggle_reqd('paid_amount', data.message ? 1 :0);
+ }
}
});
- },
- check_availability: function(frm) {
- check_and_set_availability(frm);
- },
- onload:function(frm){
- if(frm.is_new()) {
- frm.set_value("appointment_time", null);
- frm.disable_save();
- }
- },
- get_procedure_from_encounter: function(frm) {
- get_procedure_prescribed(frm);
}
});
-var check_and_set_availability = function(frm) {
- var selected_slot = null;
- var service_unit = null;
- var duration = null;
+let check_and_set_availability = function(frm) {
+ let selected_slot = null;
+ let service_unit = null;
+ let duration = null;
show_availability();
function show_empty_state(practitioner, appointment_date) {
frappe.msgprint({
title: __('Not Available'),
- message: __("Healthcare Practitioner {0} not available on {1}", [practitioner.bold(), appointment_date.bold()]),
+ message: __('Healthcare Practitioner {0} not available on {1}', [practitioner.bold(), appointment_date.bold()]),
indicator: 'red'
});
}
function show_availability() {
let selected_practitioner = '';
- var d = new frappe.ui.Dialog({
- title: __("Available slots"),
+ let d = new frappe.ui.Dialog({
+ title: __('Available slots'),
fields: [
- { fieldtype: 'Link', options: 'Medical Department', reqd:1, fieldname: 'department', label: 'Medical Department'},
+ { fieldtype: 'Link', options: 'Medical Department', reqd: 1, fieldname: 'department', label: 'Medical Department'},
{ fieldtype: 'Column Break'},
- { fieldtype: 'Link', options: 'Healthcare Practitioner', reqd:1, fieldname: 'practitioner', label: 'Healthcare Practitioner'},
+ { fieldtype: 'Link', options: 'Healthcare Practitioner', reqd: 1, fieldname: 'practitioner', label: 'Healthcare Practitioner'},
{ fieldtype: 'Column Break'},
- { fieldtype: 'Date', reqd:1, fieldname: 'appointment_date', label: 'Date'},
+ { fieldtype: 'Date', reqd: 1, fieldname: 'appointment_date', label: 'Date'},
{ fieldtype: 'Section Break'},
{ fieldtype: 'HTML', fieldname: 'available_slots'}
+
],
- primary_action_label: __("Book"),
+ primary_action_label: __('Book'),
primary_action: function() {
frm.set_value('appointment_time', selected_slot);
- frm.set_value('service_unit', service_unit || '');
frm.set_value('duration', duration);
frm.set_value('practitioner', d.get_value('practitioner'));
frm.set_value('department', d.get_value('department'));
frm.set_value('appointment_date', d.get_value('appointment_date'));
+ if (service_unit) {
+ frm.set_value('service_unit', service_unit);
+ }
d.hide();
frm.enable_save();
frm.save();
@@ -167,16 +204,16 @@
'appointment_date': frm.doc.appointment_date
});
- d.fields_dict["department"].df.onchange = () => {
+ d.fields_dict['department'].df.onchange = () => {
d.set_values({
'practitioner': ''
});
- var department = d.get_value('department');
- if(department){
+ let department = d.get_value('department');
+ if (department) {
d.fields_dict.practitioner.get_query = function() {
return {
filters: {
- "department": department
+ 'department': department
}
};
};
@@ -188,13 +225,13 @@
// Field Change Handler
- var fd = d.fields_dict;
+ let fd = d.fields_dict;
- d.fields_dict["appointment_date"].df.onchange = () => {
+ d.fields_dict['appointment_date'].df.onchange = () => {
show_slots(d, fd);
};
- d.fields_dict["practitioner"].df.onchange = () => {
- if(d.get_value('practitioner') && d.get_value('practitioner') != selected_practitioner){
+ d.fields_dict['practitioner'].df.onchange = () => {
+ if (d.get_value('practitioner') && d.get_value('practitioner') != selected_practitioner) {
selected_practitioner = d.get_value('practitioner');
show_slots(d, fd);
}
@@ -203,8 +240,8 @@
}
function show_slots(d, fd) {
- if (d.get_value('appointment_date') && d.get_value('practitioner')){
- fd.available_slots.html("");
+ if (d.get_value('appointment_date') && d.get_value('practitioner')) {
+ fd.available_slots.html('');
frappe.call({
method: 'erpnext.healthcare.doctype.patient_appointment.patient_appointment.get_availability_data',
args: {
@@ -212,13 +249,13 @@
date: d.get_value('appointment_date')
},
callback: (r) => {
- var data = r.message;
- if(data.slot_details.length > 0) {
- var $wrapper = d.fields_dict.available_slots.$wrapper;
+ let data = r.message;
+ if (data.slot_details.length > 0) {
+ let $wrapper = d.fields_dict.available_slots.$wrapper;
// make buttons for each slot
- var slot_details = data.slot_details;
- var slot_html = "";
+ let slot_details = data.slot_details;
+ let slot_html = '';
for (let i = 0; i < slot_details.length; i++) {
slot_html = slot_html + `<label>${slot_details[i].slot_name}</label>`;
slot_html = slot_html + `<br/>` + slot_details[i].avail_slot.map(slot => {
@@ -232,14 +269,14 @@
let booked_moment = moment(booked.appointment_time, 'HH:mm:ss');
let end_time = booked_moment.clone().add(booked.duration, 'minutes');
// Deal with 0 duration appointments
- if(booked_moment.isSame(slot_start_time) || booked_moment.isBetween(slot_start_time, slot_to_time)){
+ if (booked_moment.isSame(slot_start_time) || booked_moment.isBetween(slot_start_time, slot_to_time)) {
if(booked.duration == 0){
disabled = 'disabled="disabled"';
return false;
}
}
// Check for overlaps considering appointment duration
- if(slot_start_time.isBefore(end_time) && slot_to_time.isAfter(booked_moment)){
+ if (slot_start_time.isBefore(end_time) && slot_to_time.isAfter(booked_moment)) {
// There is an overlap
disabled = 'disabled="disabled"';
return false;
@@ -263,7 +300,7 @@
// blue button when clicked
$wrapper.on('click', 'button', function() {
- var $btn = $(this);
+ let $btn = $(this);
$wrapper.find('button').removeClass('btn-primary');
$btn.addClass('btn-primary');
selected_slot = $btn.attr('data-name');
@@ -273,48 +310,57 @@
d.get_primary_btn().attr('disabled', null);
});
- }else {
- // fd.available_slots.html("Please select a valid date.".bold())
+ } else {
+ // fd.available_slots.html('Please select a valid date.'.bold())
show_empty_state(d.get_value('practitioner'), d.get_value('appointment_date'));
}
},
freeze: true,
- freeze_message: __("Fetching records......")
+ freeze_message: __('Fetching records......')
});
- }else{
- fd.available_slots.html("Appointment date and Healthcare Practitioner are Mandatory".bold());
+ } else {
+ fd.available_slots.html(__('Appointment date and Healthcare Practitioner are Mandatory').bold());
}
}
};
-var get_procedure_prescribed = function(frm){
- if(frm.doc.patient){
+let get_prescribed_procedure = function(frm) {
+ if (frm.doc.patient) {
frappe.call({
- method:"erpnext.healthcare.doctype.patient_appointment.patient_appointment.get_procedure_prescribed",
+ method: 'erpnext.healthcare.doctype.patient_appointment.patient_appointment.get_procedure_prescribed',
args: {patient: frm.doc.patient},
- callback: function(r){
- show_procedure_templates(frm, r.message);
+ callback: function(r) {
+ if (r.message && r.message.length) {
+ show_procedure_templates(frm, r.message);
+ } else {
+ frappe.msgprint({
+ title: __('Not Found'),
+ message: __('No Prescribed Procedures found for the selected Patient')
+ });
+ }
}
});
- }
- else{
- frappe.msgprint(__("Please select Patient to get prescribed procedure"));
+ } else {
+ frappe.msgprint({
+ title: __('Not Allowed'),
+ message: __('Please select a Patient first')
+ });
}
};
-var show_procedure_templates = function(frm, result){
- var d = new frappe.ui.Dialog({
- title: __("Prescribed Procedures"),
+let show_procedure_templates = function(frm, result){
+ let d = new frappe.ui.Dialog({
+ title: __('Prescribed Procedures'),
fields: [
{
- fieldtype: "HTML", fieldname: "procedure_template"
+ fieldtype: 'HTML', fieldname: 'procedure_template'
}
]
});
- var html_field = d.fields_dict.procedure_template.$wrapper;
+ let html_field = d.fields_dict.procedure_template.$wrapper;
html_field.empty();
- $.each(result, function(x, y){
- var row = $(repl('<div class="col-xs-12" style="padding-top:12px; text-align:center;" >\
+ $.each(result, function(x, y) {
+ let row = $(repl('<div class="col-xs-12" style="padding-top:12px; text-align:center;" >\
<div class="col-xs-5"> %(encounter)s <br> %(consulting_practitioner)s <br> %(encounter_date)s </div>\
<div class="col-xs-5"> %(procedure_template)s <br>%(practitioner)s <br> %(date)s</div>\
<div class="col-xs-2">\
@@ -326,76 +372,47 @@
encounter:y[2], consulting_practitioner:y[3], encounter_date:y[4],
practitioner:y[5]? y[5]:'', date: y[6]? y[6]:'', department: y[7]? y[7]:''})).appendTo(html_field);
row.find("a").click(function() {
- frm.doc.procedure_template = $(this).attr("data-procedure-template");
- frm.doc.procedure_prescription = $(this).attr("data-name");
- frm.doc.practitioner = $(this).attr("data-practitioner");
- frm.doc.appointment_date = $(this).attr("data-date");
- frm.doc.department = $(this).attr("data-department");
- refresh_field("procedure_template");
- refresh_field("procedure_prescription");
- refresh_field("appointment_date");
- refresh_field("practitioner");
- refresh_field("department");
+ frm.doc.procedure_template = $(this).attr('data-procedure-template');
+ frm.doc.procedure_prescription = $(this).attr('data-name');
+ frm.doc.practitioner = $(this).attr('data-practitioner');
+ frm.doc.appointment_date = $(this).attr('data-date');
+ frm.doc.department = $(this).attr('data-department');
+ refresh_field('procedure_template');
+ refresh_field('procedure_prescription');
+ refresh_field('appointment_date');
+ refresh_field('practitioner');
+ refresh_field('department');
d.hide();
return false;
});
});
- if(!result){
- var msg = "There are no procedure prescribed for "+frm.doc.patient;
+ if (!result) {
+ let msg = __('There are no procedure prescribed for ') + frm.doc.patient;
$(repl('<div class="col-xs-12" style="padding-top:20px;" >%(msg)s</div></div>', {msg: msg})).appendTo(html_field);
}
d.show();
};
-var btn_create_procedure = function(frm){
- var doc = frm.doc;
- frappe.call({
- method:"erpnext.healthcare.doctype.clinical_procedure.clinical_procedure.create_procedure",
- args: {appointment: doc.name},
- callback: function(data){
- if(!data.exc){
- var doclist = frappe.model.sync(data.message);
- frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
- }
- }
- });
-};
-
-var btn_create_encounter = function(frm){
- var doc = frm.doc;
- frappe.call({
- method:"erpnext.healthcare.doctype.patient_appointment.patient_appointment.create_encounter",
- args: {appointment: doc.name},
- callback: function(data){
- if(!data.exc){
- var doclist = frappe.model.sync(data.message);
- frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
- }
- }
- });
-};
-
-var btn_create_vital_signs = function (frm) {
- if(!frm.doc.patient){
- frappe.throw(__("Please select patient"));
+let create_vital_signs = function(frm) {
+ if (!frm.doc.patient) {
+ frappe.throw(__('Please select patient'));
}
frappe.route_options = {
- "patient": frm.doc.patient,
- "appointment": frm.doc.name,
+ 'patient': frm.doc.patient,
+ 'appointment': frm.doc.name,
};
- frappe.new_doc("Vital Signs");
+ frappe.new_doc('Vital Signs');
};
-var btn_update_status = function(frm, status){
- var doc = frm.doc;
+let update_status = function(frm, status){
+ let doc = frm.doc;
frappe.confirm(__('Are you sure you want to cancel this appointment?'),
function() {
frappe.call({
- method:
- "erpnext.healthcare.doctype.patient_appointment.patient_appointment.update_status",
+ method: 'erpnext.healthcare.doctype.patient_appointment.patient_appointment.update_status',
args: {appointment_id: doc.name, status:status},
- callback: function(data){
- if(!data.exc){
+ callback: function(data) {
+ if (!data.exc) {
frm.reload_doc();
}
}
@@ -404,60 +421,60 @@
);
};
-frappe.ui.form.on("Patient Appointment", "practitioner", function(frm) {
- if(frm.doc.practitioner){
+frappe.ui.form.on('Patient Appointment', 'practitioner', function(frm) {
+ if (frm.doc.practitioner) {
frappe.call({
- "method": "frappe.client.get",
+ method: 'frappe.client.get',
args: {
- doctype: "Healthcare Practitioner",
+ doctype: 'Healthcare Practitioner',
name: frm.doc.practitioner
},
callback: function (data) {
- frappe.model.set_value(frm.doctype,frm.docname, "department",data.message.department);
- frappe.model.set_value(frm.doctype,frm.docname, "paid_amount",data.message.op_consulting_charge);
+ frappe.model.set_value(frm.doctype, frm.docname, 'department', data.message.department);
+ frappe.model.set_value(frm.doctype, frm.docname, 'paid_amount', data.message.op_consulting_charge);
}
});
}
});
-frappe.ui.form.on("Patient Appointment", "patient", function(frm) {
- if(frm.doc.patient){
+frappe.ui.form.on('Patient Appointment', 'patient', function(frm) {
+ if (frm.doc.patient) {
frappe.call({
- "method": "frappe.client.get",
+ method: 'frappe.client.get',
args: {
- doctype: "Patient",
+ doctype: 'Patient',
name: frm.doc.patient
},
callback: function (data) {
- var age = null;
- if(data.message.dob){
+ let age = null;
+ if (data.message.dob) {
age = calculate_age(data.message.dob);
}
- frappe.model.set_value(frm.doctype,frm.docname, "patient_age", age);
+ frappe.model.set_value(frm.doctype,frm.docname, 'patient_age', age);
}
});
}
});
-frappe.ui.form.on("Patient Appointment", "appointment_type", function(frm) {
- if(frm.doc.appointment_type) {
+frappe.ui.form.on('Patient Appointment', 'appointment_type', function(frm) {
+ if (frm.doc.appointment_type) {
frappe.call({
- "method": "frappe.client.get",
+ method: 'frappe.client.get',
args: {
- doctype: "Appointment Type",
+ doctype: 'Appointment Type',
name: frm.doc.appointment_type
},
- callback: function (data) {
- frappe.model.set_value(frm.doctype,frm.docname, "duration",data.message.default_duration);
+ callback: function(data) {
+ frappe.model.set_value(frm.doctype,frm.docname, 'duration',data.message.default_duration);
}
});
}
});
-var calculate_age = function(birth) {
- var ageMS = Date.parse(Date()) - Date.parse(birth);
- var age = new Date();
+let calculate_age = function(birth) {
+ let ageMS = Date.parse(Date()) - Date.parse(birth);
+ let age = new Date();
age.setTime(ageMS);
- var years = age.getFullYear() - 1970;
- return years + " Year(s) " + age.getMonth() + " Month(s) " + age.getDate() + " Day(s)";
+ let years = age.getFullYear() - 1970;
+ return years + ' Year(s) ' + age.getMonth() + ' Month(s) ' + age.getDate() + ' Day(s)';
};
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
index ee9f013..7f9a671 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
@@ -1,1177 +1,333 @@
{
+ "actions": [],
"allow_copy": 1,
- "allow_events_in_timeline": 0,
- "allow_guest_to_view": 0,
"allow_import": 1,
- "allow_rename": 0,
- "autoname": "OP-.######",
+ "autoname": "naming_series:",
"beta": 1,
"creation": "2017-05-04 11:52:40.941507",
- "custom": 0,
- "docstatus": 0,
"doctype": "DocType",
"document_type": "Document",
- "editable_grid": 0,
"engine": "InnoDB",
+ "field_order": [
+ "naming_series",
+ "patient",
+ "patient_name",
+ "patient_sex",
+ "patient_age",
+ "inpatient_record",
+ "column_break_1",
+ "status",
+ "procedure_template",
+ "get_procedure_from_encounter",
+ "procedure_prescription",
+ "service_unit",
+ "section_break_12",
+ "practitioner",
+ "department",
+ "appointment_type",
+ "column_break_17",
+ "appointment_date",
+ "appointment_time",
+ "appointment_datetime",
+ "duration",
+ "section_break_16",
+ "mode_of_payment",
+ "paid_amount",
+ "company",
+ "column_break_2",
+ "invoiced",
+ "ref_sales_invoice",
+ "section_break_3",
+ "notes",
+ "referring_practitioner",
+ "reminded"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fetch_from": "patient.inpatient_record",
"fieldname": "inpatient_record",
"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": "Inpatient Record",
- "length": 0,
- "no_copy": 0,
"options": "Inpatient Record",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "read_only": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fetch_from": "inpatient_record.patient",
"fieldname": "patient",
"fieldtype": "Link",
- "hidden": 0,
"ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Patient",
- "length": 0,
- "no_copy": 0,
"options": "Patient",
- "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": 1,
- "set_only_once": 1,
- "translatable": 0,
- "unique": 0
+ "set_only_once": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "appointment_type",
"fieldtype": "Link",
- "hidden": 0,
"ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Appointment Type",
- "length": 0,
- "no_copy": 0,
"options": "Appointment Type",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 1,
- "translatable": 0,
- "unique": 0
+ "set_only_once": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "In Minutes",
"fieldname": "duration",
"fieldtype": "Int",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
"in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Duration",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Duration (In Minutes)"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "column_break_1",
"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,
- "label": "",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "read_only": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "Scheduled",
"depends_on": "eval:!doc.__islocal",
"fieldname": "status",
"fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
"in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
+ "in_list_view": 1,
"label": "Status",
- "length": 0,
- "no_copy": 0,
- "options": "\nScheduled\nOpen\nClosed\nPending\nCancelled",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
+ "options": "\nScheduled\nOpen\nClosed\nCancelled",
"read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "search_index": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "procedure_template",
"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": "Procedure",
- "length": 0,
- "no_copy": 0,
+ "label": "Clinical Procedure Template",
"options": "Clinical Procedure Template",
- "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": 1,
- "translatable": 0,
- "unique": 0
+ "set_only_once": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
+ "depends_on": "eval:doc.__islocal && doc.patient",
"fieldname": "get_procedure_from_encounter",
"fieldtype": "Button",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Get prescribed procedures",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Get Prescribed Clinical Procedures"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "procedure_prescription",
"fieldtype": "Link",
"hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Procedure Prescription",
- "length": 0,
"no_copy": 1,
"options": "Procedure Prescription",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "print_hide": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "service_unit",
"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": "Service Unit",
- "length": 0,
- "no_copy": 0,
"options": "Healthcare Service Unit",
- "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": 1,
- "translatable": 0,
- "unique": 0
+ "set_only_once": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:doc.__islocal",
- "fieldname": "check_availability",
- "fieldtype": "Button",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Check availability",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "section_break_12",
- "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,
- "translatable": 0,
- "unique": 0
+ "fieldtype": "Section Break"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "practitioner",
"fieldtype": "Link",
- "hidden": 0,
"ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
"in_standard_filter": 1,
"label": "Healthcare Practitioner",
- "length": 0,
- "no_copy": 0,
"options": "Healthcare Practitioner",
- "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": 1,
- "set_only_once": 1,
- "translatable": 0,
- "unique": 0
+ "set_only_once": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "department",
"fieldtype": "Link",
- "hidden": 0,
"ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Department",
- "length": 0,
- "no_copy": 0,
"options": "Medical Department",
- "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": 1,
- "set_only_once": 1,
- "translatable": 0,
- "unique": 0
+ "set_only_once": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "column_break_17",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "fieldtype": "Column Break"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "appointment_date",
"fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Date",
- "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": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "search_index": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "appointment_time",
"fieldtype": "Time",
- "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": "Time",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "read_only": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "section_break_16",
- "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,
- "translatable": 0,
- "unique": 0
+ "fieldtype": "Section Break"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
"fetch_from": "patient.patient_name",
"fieldname": "patient_name",
"fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Patient Name",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "read_only": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fetch_from": "patient.sex",
"fieldname": "patient_sex",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
+ "fieldtype": "Link",
"label": "Gender",
- "length": 0,
"no_copy": 1,
- "options": "",
- "permlevel": 0,
- "precision": "",
+ "options": "Gender",
"print_hide": 1,
- "print_hide_if_no_value": 0,
"read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "report_hide": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_21",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "patient_age",
"fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Patient Age",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "read_only": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "section_break_1",
- "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": 1,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "appointment_datetime",
"fieldtype": "Datetime",
- "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": "Date TIme",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
+ "label": "Appointment Datetime",
"print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
+ "read_only": 1,
"report_hide": 1,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "search_index": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "mode_of_payment",
"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": "Mode of Payment",
- "length": 0,
- "no_copy": 0,
- "options": "Mode of Payment",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "options": "Mode of Payment"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "paid_amount",
"fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Paid Amount",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Paid Amount"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "column_break_2",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "fieldtype": "Column Break"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"default": "0",
"fieldname": "invoiced",
"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": "Invoiced",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "read_only": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Company",
- "length": 0,
"no_copy": 1,
"options": "Company",
- "permlevel": 0,
- "precision": "",
"print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "report_hide": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
"collapsible": 1,
- "columns": 0,
"fieldname": "section_break_3",
"fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "More Info",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "More Info"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "notes",
"fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
"ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Notes",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Notes"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "referring_practitioner",
"fieldtype": "Link",
- "hidden": 0,
"ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Referring Practitioner",
- "length": 0,
- "no_copy": 0,
- "options": "Healthcare Practitioner",
- "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": 1,
- "translatable": 0,
- "unique": 0
+ "options": "Healthcare Practitioner"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"default": "0",
"fieldname": "reminded",
"fieldtype": "Check",
"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": "Reminded",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
"print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "report_hide": 1
+ },
+ {
+ "fieldname": "ref_sales_invoice",
+ "fieldtype": "Link",
+ "label": "Reference Sales Invoice",
+ "options": "Sales Invoice",
+ "read_only": 1
+ },
+ {
+ "fieldname": "naming_series",
+ "fieldtype": "Select",
+ "label": "Series",
+ "options": "HLC-APP-.YYYY.-",
+ "set_only_once": 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": 0,
- "max_attachments": 0,
- "modified": "2018-11-14 13:24:01.529536",
+ "links": [],
+ "modified": "2020-03-27 11:27:33.773195",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Patient Appointment",
- "name_case": "",
"owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Healthcare Administrator",
- "set_user_permissions": 0,
"share": 1,
- "submit": 0,
"write": 1
},
{
- "amend": 0,
- "cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Physician",
- "set_user_permissions": 0,
"share": 1,
- "submit": 0,
"write": 1
},
{
- "amend": 0,
- "cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Nursing User",
- "set_user_permissions": 0,
"share": 1,
- "submit": 0,
"write": 1
}
],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
"restrict_to_domain": "Healthcare",
"search_fields": "patient, practitioner, department, appointment_date, appointment_time",
"show_name_in_global_search": 1,
@@ -1179,6 +335,5 @@
"sort_order": "DESC",
"title_field": "patient",
"track_changes": 1,
- "track_seen": 1,
- "track_views": 0
-}
+ "track_seen": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
index 5f48c9f..a2d9d02 100755
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
@@ -6,26 +6,42 @@
import frappe
from frappe.model.document import Document
import json
-from frappe.utils import getdate, add_days, get_time
+from frappe.utils import getdate, get_time
+from frappe.model.mapper import get_mapped_doc
from frappe import _
import datetime
from frappe.core.doctype.sms_settings.sms_settings import send_sms
from erpnext.hr.doctype.employee.employee import is_holiday
-from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account,get_income_account
-from erpnext.healthcare.utils import validity_exists, service_item_and_practitioner_charge
+from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account, get_income_account
+from erpnext.healthcare.utils import check_fee_validity, get_service_item_and_practitioner_charge, manage_fee_validity
class PatientAppointment(Document):
- def on_update(self):
- today = datetime.date.today()
+ def validate(self):
+ self.validate_overlaps()
+ self.set_appointment_datetime()
+ self.validate_customer_created()
+ self.set_status()
+
+ def after_insert(self):
+ self.update_prescription_details()
+ invoice_appointment(self)
+ self.update_fee_validity()
+ send_confirmation_msg(self)
+
+ def set_status(self):
+ today = getdate()
appointment_date = getdate(self.appointment_date)
- # If appointment created for today set as open
- if today == appointment_date:
- frappe.db.set_value("Patient Appointment", self.name, "status", "Open")
- self.reload()
+ # If appointment is created for today set status as Open else Scheduled
+ if appointment_date == today:
+ self.status = 'Open'
+ elif appointment_date > today:
+ self.status = 'Scheduled'
- def validate(self):
- end_time = datetime.datetime.combine(getdate(self.appointment_date), get_time(self.appointment_time)) + datetime.timedelta(minutes=float(self.duration))
+ def validate_overlaps(self):
+ end_time = datetime.datetime.combine(getdate(self.appointment_date), get_time(self.appointment_time)) \
+ + datetime.timedelta(minutes=float(self.duration))
+
overlaps = frappe.db.sql("""
select
name, practitioner, patient, appointment_time, duration
@@ -41,135 +57,153 @@
self.appointment_time, end_time.time(), self.appointment_time, end_time.time(), self.appointment_time))
if overlaps:
- frappe.throw(_("""Appointment overlaps with {0}.<br> {1} has appointment scheduled
- with {2} at {3} having {4} minute(s) duration.""").format(overlaps[0][0], overlaps[0][1], overlaps[0][2], overlaps[0][3], overlaps[0][4]))
+ overlapping_details = _('Appointment overlaps with ')
+ overlapping_details += "<b><a href='#Form/Patient Appointment/{0}'>{0}</a></b><br>".format(overlaps[0][0])
+ overlapping_details += _('{0} has appointment scheduled with {1} at {2} having {3} minute(s) duration.').format(
+ overlaps[0][1], overlaps[0][2], overlaps[0][3], overlaps[0][4])
+ frappe.throw(overlapping_details, title=_('Appointments Overlapping'))
- def after_insert(self):
+ def set_appointment_datetime(self):
+ self.appointment_datetime = "%s %s" % (self.appointment_date, self.appointment_time or "00:00:00")
+
+ def validate_customer_created(self):
+ if frappe.db.get_single_value('Healthcare Settings', 'automate_appointment_invoicing'):
+ if not frappe.db.get_value('Patient', self.patient, 'customer'):
+ msg = _("Please set a Customer linked to the Patient")
+ msg += " <b><a href='#Form/Patient/{0}'>{0}</a></b>".format(self.patient)
+ frappe.throw(msg, title=_('Customer Not Found'))
+
+ def update_prescription_details(self):
if self.procedure_prescription:
- frappe.db.set_value("Procedure Prescription", self.procedure_prescription, "appointment_booked", True)
+ frappe.db.set_value('Procedure Prescription', self.procedure_prescription, 'appointment_booked', 1)
if self.procedure_template:
- comments = frappe.db.get_value("Procedure Prescription", self.procedure_prescription, "comments")
+ comments = frappe.db.get_value('Procedure Prescription', self.procedure_prescription, 'comments')
if comments:
- frappe.db.set_value("Patient Appointment", self.name, "notes", comments)
- # Check fee validity exists
- appointment = self
- validity_exist = validity_exists(appointment.practitioner, appointment.patient)
- if validity_exist:
- fee_validity = frappe.get_doc("Fee Validity", validity_exist[0][0])
+ frappe.db.set_value('Patient Appointment', self.name, 'notes', comments)
- # Check if the validity is valid
- appointment_date = getdate(appointment.appointment_date)
- if (fee_validity.valid_till >= appointment_date) and (fee_validity.visited < fee_validity.max_visit):
- visited = fee_validity.visited + 1
- frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
- if fee_validity.ref_invoice:
- frappe.db.set_value("Patient Appointment", appointment.name, "invoiced", True)
- frappe.msgprint(_("{0} has fee validity till {1}").format(appointment.patient, fee_validity.valid_till))
- confirm_sms(self)
+ def update_fee_validity(self):
+ fee_validity = manage_fee_validity(self)
+ if fee_validity:
+ frappe.msgprint(_('{0} has fee validity till {1}').format(self.patient, fee_validity.valid_till))
- if frappe.db.get_value("Healthcare Settings", None, "manage_appointment_invoice_automatically") == '1' and \
- frappe.db.get_value("Patient Appointment", self.name, "invoiced") != 1:
- invoice_appointment(self)
@frappe.whitelist()
-def invoice_appointment(appointment_doc):
- if not appointment_doc.name:
- return False
- sales_invoice = frappe.new_doc("Sales Invoice")
- sales_invoice.customer = frappe.get_value("Patient", appointment_doc.patient, "customer")
- sales_invoice.appointment = appointment_doc.name
- sales_invoice.due_date = getdate()
- sales_invoice.is_pos = True
- sales_invoice.company = appointment_doc.company
- sales_invoice.debit_to = get_receivable_account(appointment_doc.company)
-
- item_line = sales_invoice.append("items")
- service_item, practitioner_charge = service_item_and_practitioner_charge(appointment_doc)
- item_line.item_code = service_item
- item_line.description = "Consulting Charges: " + appointment_doc.practitioner
- item_line.income_account = get_income_account(appointment_doc.practitioner, appointment_doc.company)
- item_line.rate = practitioner_charge
- item_line.amount = practitioner_charge
- item_line.qty = 1
- item_line.reference_dt = "Patient Appointment"
- item_line.reference_dn = appointment_doc.name
-
- payments_line = sales_invoice.append("payments")
- payments_line.mode_of_payment = appointment_doc.mode_of_payment
- payments_line.amount = appointment_doc.paid_amount
-
- sales_invoice.set_missing_values(for_validate = True)
-
- sales_invoice.save(ignore_permissions=True)
- sales_invoice.submit()
- frappe.msgprint(_("Sales Invoice {0} created as paid").format(sales_invoice.name), alert=True)
-
-def appointment_cancel(appointment_id):
- appointment = frappe.get_doc("Patient Appointment", appointment_id)
- # If invoiced --> fee_validity update with -1 visit
- if appointment.invoiced:
- sales_invoice = exists_sales_invoice(appointment)
- if sales_invoice and cancel_sales_invoice(sales_invoice):
- frappe.msgprint(
- _("Appointment {0} and Sales Invoice {1} cancelled").format(appointment.name, sales_invoice.name)
- )
- else:
- validity = validity_exists(appointment.practitioner, appointment.patient)
- if validity:
- fee_validity = frappe.get_doc("Fee Validity", validity[0][0])
- if appointment_valid_in_fee_validity(appointment, fee_validity.valid_till, True, fee_validity.ref_invoice):
- visited = fee_validity.visited - 1
- frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
- frappe.msgprint(
- _("Appointment cancelled, Please review and cancel the invoice {0}").format(fee_validity.ref_invoice)
- )
- else:
- frappe.msgprint(_("Appointment cancelled"))
- else:
- frappe.msgprint(_("Appointment cancelled"))
- else:
- frappe.msgprint(_("Appointment cancelled"))
-
-def appointment_valid_in_fee_validity(appointment, valid_end_date, invoiced, ref_invoice):
- valid_days = frappe.db.get_value("Healthcare Settings", None, "valid_days")
- max_visit = frappe.db.get_value("Healthcare Settings", None, "max_visit")
- valid_start_date = add_days(getdate(valid_end_date), -int(valid_days))
-
- # Appointments which has same fee validity range with the appointment
- appointments = frappe.get_list("Patient Appointment",{'patient': appointment.patient, 'invoiced': invoiced,
- 'appointment_date':("<=", getdate(valid_end_date)), 'appointment_date':(">=", getdate(valid_start_date)),
- 'practitioner': appointment.practitioner}, order_by="appointment_date desc", limit=int(max_visit))
-
- if appointments and len(appointments) > 0:
- appointment_obj = appointments[len(appointments)-1]
- sales_invoice = exists_sales_invoice(appointment_obj)
- if sales_invoice.name == ref_invoice:
- return True
+def check_payment_fields_reqd(patient):
+ automate_invoicing = frappe.db.get_single_value('Healthcare Settings', 'automate_appointment_invoicing')
+ free_follow_ups = frappe.db.get_single_value('Healthcare Settings', 'enable_free_follow_ups')
+ if automate_invoicing:
+ if free_follow_ups:
+ fee_validity = frappe.db.exists('Fee Validity', {'patient': patient, 'status': 'Pending'})
+ if fee_validity:
+ return {'fee_validity': fee_validity}
+ if check_is_new_patient(patient):
+ return False
+ return True
return False
+def invoice_appointment(appointment_doc):
+ automate_invoicing = frappe.db.get_single_value('Healthcare Settings', 'automate_appointment_invoicing')
+ appointment_invoiced = frappe.db.get_value('Patient Appointment', appointment_doc.name, 'invoiced')
+ enable_free_follow_ups = frappe.db.get_single_value('Healthcare Settings', 'enable_free_follow_ups')
+ if enable_free_follow_ups:
+ fee_validity = check_fee_validity(appointment_doc)
+ if fee_validity and fee_validity.status == 'Completed':
+ fee_validity = None
+ elif not fee_validity:
+ if frappe.db.exists('Fee Validity Reference', {'appointment': appointment_doc.name}):
+ return
+ if check_is_new_patient(appointment_doc.patient, appointment_doc.name):
+ return
+ else:
+ fee_validity = None
+
+ if automate_invoicing and not appointment_invoiced and not fee_validity:
+ sales_invoice = frappe.new_doc('Sales Invoice')
+ sales_invoice.customer = frappe.get_value('Patient', appointment_doc.patient, 'customer')
+ sales_invoice.appointment = appointment_doc.name
+ sales_invoice.due_date = getdate()
+ sales_invoice.is_pos = 1
+ sales_invoice.company = appointment_doc.company
+ sales_invoice.debit_to = get_receivable_account(appointment_doc.company)
+
+ item = sales_invoice.append('items', {})
+ item = get_appointment_item(appointment_doc, item)
+
+ payment = sales_invoice.append('payments', {})
+ payment.mode_of_payment = appointment_doc.mode_of_payment
+ payment.amount = appointment_doc.paid_amount
+
+ sales_invoice.set_missing_values(for_validate=True)
+ sales_invoice.flags.ignore_mandatory = True
+ sales_invoice.save(ignore_permissions=True)
+ sales_invoice.submit()
+ frappe.msgprint(_('Sales Invoice {0} created as paid'.format(sales_invoice.name)), alert=True)
+ frappe.db.set_value('Patient Appointment', appointment_doc.name, 'invoiced', 1)
+ frappe.db.set_value('Patient Appointment', appointment_doc.name, 'ref_sales_invoice', sales_invoice.name)
+
+
+def check_is_new_patient(patient, name=None):
+ filters = {'patient': patient, 'status': ('!=','Cancelled')}
+ if name:
+ filters['name'] = ('!=', name)
+
+ has_previous_appointment = frappe.db.exists('Patient Appointment', filters)
+ if has_previous_appointment:
+ return False
+ return True
+
+
+def get_appointment_item(appointment_doc, item):
+ service_item, practitioner_charge = get_service_item_and_practitioner_charge(appointment_doc)
+ item.item_code = service_item
+ item.description = _('Consulting Charges: {0}').format(appointment_doc.practitioner)
+ item.income_account = get_income_account(appointment_doc.practitioner, appointment_doc.company)
+ item.cost_center = frappe.get_cached_value('Company', appointment_doc.company, 'cost_center')
+ item.rate = practitioner_charge
+ item.amount = practitioner_charge
+ item.qty = 1
+ item.reference_dt = 'Patient Appointment'
+ item.reference_dn = appointment_doc.name
+ return item
+
+
+def cancel_appointment(appointment_id):
+ appointment = frappe.get_doc('Patient Appointment', appointment_id)
+ if appointment.invoiced:
+ sales_invoice = check_sales_invoice_exists(appointment)
+ if sales_invoice and cancel_sales_invoice(sales_invoice):
+ msg = _('Appointment {0} and Sales Invoice {1} cancelled').format(appointment.name, sales_invoice.name)
+ else:
+ msg = _('Appointment Cancelled. Please review and cancel the invoice {0}').format(sales_invoice.name)
+ else:
+ fee_validity = manage_fee_validity(appointment)
+ msg = _('Appointment Cancelled.')
+ if fee_validity:
+ msg += _('Fee Validity {0} updated.').format(fee_validity.name)
+
+ frappe.msgprint(msg)
+
+
def cancel_sales_invoice(sales_invoice):
- if frappe.db.get_value("Healthcare Settings", None, "manage_appointment_invoice_automatically") == '1':
+ if frappe.db.get_single_value('Healthcare Settings', 'automate_appointment_invoicing'):
if len(sales_invoice.items) == 1:
sales_invoice.cancel()
return True
return False
-def exists_sales_invoice_item(appointment):
- return frappe.db.exists(
- "Sales Invoice Item",
- {
- "reference_dt": "Patient Appointment",
- "reference_dn": appointment.name
- }
- )
-def exists_sales_invoice(appointment):
- sales_item_exist = exists_sales_invoice_item(appointment)
- if sales_item_exist:
- sales_invoice = frappe.get_doc("Sales Invoice", frappe.db.get_value("Sales Invoice Item", sales_item_exist, "parent"))
+def check_sales_invoice_exists(appointment):
+ sales_invoice = frappe.db.get_value('Sales Invoice Item', {
+ 'reference_dt': 'Patient Appointment',
+ 'reference_dn': appointment.name
+ }, 'parent')
+
+ if sales_invoice:
+ sales_invoice = frappe.get_doc('Sales Invoice', sales_invoice)
return sales_invoice
return False
+
@frappe.whitelist()
def get_availability_data(date, practitioner):
"""
@@ -180,169 +214,163 @@
"""
date = getdate(date)
- weekday = date.strftime("%A")
+ weekday = date.strftime('%A')
- available_slots = []
- slot_details = []
- practitioner_schedule = None
+ practitioner_doc = frappe.get_doc('Healthcare Practitioner', practitioner)
+ check_employee_wise_availability(date, practitioner_doc)
+
+ if practitioner_doc.practitioner_schedules:
+ slot_details = get_available_slots(practitioner_doc, date)
+ else:
+ frappe.throw(_('{0} does not have a Healthcare Practitioner Schedule. Add it in Healthcare Practitioner master').format(
+ practitioner), title=_('Practitioner Schedule Not Found'))
+
+
+ if not slot_details:
+ # TODO: return available slots in nearby dates
+ frappe.throw(_('Healthcare Practitioner not available on {0}').format(weekday), title=_('Not Available'))
+
+ return {'slot_details': slot_details}
+
+
+def check_employee_wise_availability(date, practitioner_doc):
employee = None
-
- practitioner_obj = frappe.get_doc("Healthcare Practitioner", practitioner)
-
- # Get practitioner employee relation
- if practitioner_obj.employee:
- employee = practitioner_obj.employee
- elif practitioner_obj.user_id:
- if frappe.db.exists({
- "doctype": "Employee",
- "user_id": practitioner_obj.user_id
- }):
- employee = frappe.get_doc("Employee", {"user_id": practitioner_obj.user_id}).name
+ if practitioner_doc.employee:
+ employee = practitioner_doc.employee
+ elif practitioner_doc.user_id:
+ employee = frappe.db.get_value('Employee', {'user_id': practitioner_doc.user_id}, 'name')
if employee:
- # Check if it is Holiday
+ # check holiday
if is_holiday(employee, date):
- frappe.throw(_("{0} is a company holiday").format(date))
+ frappe.throw(_('{0} is a holiday'.format(date)), title=_('Not Available'))
- # Check if He/She on Leave
+ # check leave status
leave_record = frappe.db.sql("""select half_day from `tabLeave Application`
where employee = %s and %s between from_date and to_date
and docstatus = 1""", (employee, date), as_dict=True)
if leave_record:
if leave_record[0].half_day:
- frappe.throw(_("{0} on Half day Leave on {1}").format(practitioner, date))
+ frappe.throw(_('{0} is on a Half day Leave on {1}').format(practitioner_doc.name, date), title=_('Not Available'))
else:
- frappe.throw(_("{0} on Leave on {1}").format(practitioner, date))
+ frappe.throw(_('{0} is on Leave on {1}').format(practitioner_doc.name, date), title=_('Not Available'))
- # get practitioners schedule
- if practitioner_obj.practitioner_schedules:
- for schedule in practitioner_obj.practitioner_schedules:
- if schedule.schedule:
- practitioner_schedule = frappe.get_doc("Practitioner Schedule", schedule.schedule)
- else:
- frappe.throw(_("{0} does not have a Healthcare Practitioner Schedule. Add it in Healthcare Practitioner master").format(practitioner))
- if practitioner_schedule:
- available_slots = []
- for t in practitioner_schedule.time_slots:
- if weekday == t.day:
- available_slots.append(t)
+def get_available_slots(practitioner_doc, date):
+ available_slots = []
+ slot_details = []
+ weekday = date.strftime('%A')
+ practitioner = practitioner_doc.name
- if available_slots:
- appointments = []
+ for schedule_entry in practitioner_doc.practitioner_schedules:
+ if schedule_entry.schedule:
+ practitioner_schedule = frappe.get_doc('Practitioner Schedule', schedule_entry.schedule)
+ else:
+ frappe.throw(_('{0} does not have a Healthcare Practitioner Schedule. Add it in Healthcare Practitioner').format(
+ frappe.bold(practitioner)), title=_('Practitioner Schedule Not Found'))
- if schedule.service_unit:
- slot_name = schedule.schedule+" - "+schedule.service_unit
- allow_overlap = frappe.get_value('Healthcare Service Unit', schedule.service_unit, 'overlap_appointments')
- if allow_overlap:
- # fetch all appointments to practitioner by service unit
- appointments = frappe.get_all(
- "Patient Appointment",
- filters={"practitioner": practitioner, "service_unit": schedule.service_unit, "appointment_date": date, "status": ["not in",["Cancelled"]]},
- fields=["name", "appointment_time", "duration", "status"])
- else:
- # fetch all appointments to service unit
- appointments = frappe.get_all(
- "Patient Appointment",
- filters={"service_unit": schedule.service_unit, "appointment_date": date, "status": ["not in",["Cancelled"]]},
- fields=["name", "appointment_time", "duration", "status"])
- else:
- slot_name = schedule.schedule
- # fetch all appointments to practitioner without service unit
- appointments = frappe.get_all(
- "Patient Appointment",
- filters={"practitioner": practitioner, "service_unit": '', "appointment_date": date, "status": ["not in",["Cancelled"]]},
- fields=["name", "appointment_time", "duration", "status"])
+ if practitioner_schedule:
+ available_slots = []
+ for time_slot in practitioner_schedule.time_slots:
+ if weekday == time_slot.day:
+ available_slots.append(time_slot)
- slot_details.append({"slot_name":slot_name, "service_unit":schedule.service_unit,
- "avail_slot":available_slots, 'appointments': appointments})
+ if available_slots:
+ appointments = []
+ # fetch all appointments to practitioner by service unit
+ filters = {
+ 'practitioner': practitioner,
+ 'service_unit': schedule_entry.service_unit,
+ 'appointment_date': date,
+ 'status': ['not in',['Cancelled']]
+ }
- else:
- frappe.throw(_("{0} does not have a Healthcare Practitioner Schedule. Add it in Healthcare Practitioner master").format(practitioner))
+ if schedule_entry.service_unit:
+ slot_name = schedule_entry.schedule + ' - ' + schedule_entry.service_unit
+ allow_overlap = frappe.get_value('Healthcare Service Unit', schedule_entry.service_unit, 'overlap_appointments')
+ if not allow_overlap:
+ # fetch all appointments to service unit
+ filters.pop('practitioner')
+ else:
+ slot_name = schedule_entry.schedule
+ # fetch all appointments to practitioner without service unit
+ filters['practitioner'] = practitioner
+ filters.pop('service_unit')
- if not available_slots and not slot_details:
- # TODO: return available slots in nearby dates
- frappe.throw(_("Healthcare Practitioner not available on {0}").format(weekday))
+ appointments = frappe.get_all(
+ 'Patient Appointment',
+ filters=filters,
+ fields=['name', 'appointment_time', 'duration', 'status'])
- return {
- "slot_details": slot_details
- }
+ slot_details.append({'slot_name':slot_name, 'service_unit':schedule_entry.service_unit,
+ 'avail_slot':available_slots, 'appointments': appointments})
+
+ return slot_details
@frappe.whitelist()
def update_status(appointment_id, status):
- frappe.db.set_value("Patient Appointment", appointment_id, "status", status)
+ frappe.db.set_value('Patient Appointment', appointment_id, 'status', status)
appointment_booked = True
- if status == "Cancelled":
+ if status == 'Cancelled':
appointment_booked = False
- appointment_cancel(appointment_id)
+ cancel_appointment(appointment_id)
- procedure_prescription = frappe.db.get_value("Patient Appointment", appointment_id, "procedure_prescription")
+ procedure_prescription = frappe.db.get_value('Patient Appointment', appointment_id, 'procedure_prescription')
if procedure_prescription:
- frappe.db.set_value("Procedure Prescription", procedure_prescription, "appointment_booked", appointment_booked)
+ frappe.db.set_value('Procedure Prescription', procedure_prescription, 'appointment_booked', appointment_booked)
-@frappe.whitelist()
-def set_open_appointments():
- today = getdate()
- frappe.db.sql(
- "update `tabPatient Appointment` set status='Open' where status = 'Scheduled'"
- " and appointment_date = %s", today)
-
-
-@frappe.whitelist()
-def set_pending_appointments():
- today = getdate()
- frappe.db.sql(
- "update `tabPatient Appointment` set status='Pending' where status in "
- "('Scheduled','Open') and appointment_date < %s", today)
-
-
-def confirm_sms(doc):
- if frappe.db.get_value("Healthcare Settings", None, "app_con") == '1':
- message = frappe.db.get_value("Healthcare Settings", None, "app_con_msg")
+def send_confirmation_msg(doc):
+ if frappe.db.get_single_value('Healthcare Settings', 'send_appointment_confirmation'):
+ message = frappe.db.get_single_value('Healthcare Settings', 'appointment_confirmation_msg')
send_message(doc, message)
+
@frappe.whitelist()
-def create_encounter(appointment):
- appointment = frappe.get_doc("Patient Appointment", appointment)
- encounter = frappe.new_doc("Patient Encounter")
- encounter.appointment = appointment.name
- encounter.patient = appointment.patient
- encounter.practitioner = appointment.practitioner
- encounter.visit_department = appointment.department
- encounter.patient_sex = appointment.patient_sex
- encounter.encounter_date = appointment.appointment_date
- if appointment.invoiced:
- encounter.invoiced = True
- return encounter.as_dict()
+def make_encounter(source_name, target_doc=None):
+ doc = get_mapped_doc('Patient Appointment', source_name, {
+ 'Patient Appointment': {
+ 'doctype': 'Patient Encounter',
+ 'field_map': [
+ ['appointment', 'name'],
+ ['patient', 'patient'],
+ ['practitioner', 'practitioner'],
+ ['medical_department', 'department'],
+ ['patient_sex', 'patient_sex'],
+ ['encounter_date', 'appointment_date'],
+ ['invoiced', 'invoiced']
+ ]
+ }
+ }, target_doc)
+ return doc
-def remind_appointment():
- if frappe.db.get_value("Healthcare Settings", None, "app_rem") == '1':
- rem_before = datetime.datetime.strptime(frappe.get_value("Healthcare Settings", None, "rem_before"), "%H:%M:%S")
- rem_dt = datetime.datetime.now() + datetime.timedelta(
- hours=rem_before.hour, minutes=rem_before.minute, seconds=rem_before.second)
+def send_appointment_reminder():
+ if frappe.db.get_single_value('Healthcare Settings', 'send_appointment_reminder'):
+ remind_before = datetime.datetime.strptime(frappe.db.get_single_value('Healthcare Settings', 'remind_before'), '%H:%M:%S')
+ reminder_dt = datetime.datetime.now() + datetime.timedelta(
+ hours=remind_before.hour, minutes=remind_before.minute, seconds=remind_before.second)
- appointment_list = frappe.db.sql(
- "select name from `tabPatient Appointment` where start_dt between %s and %s and reminded = 0 ",
- (datetime.datetime.now(), rem_dt)
- )
+ appointment_list = frappe.db.get_all('Patient Appointment', {
+ 'appointment_datetime': ['between', (datetime.datetime.now(), reminder_dt)],
+ 'reminded': 0,
+ 'status': ['!=', 'Cancelled']
+ })
- for i in range(0, len(appointment_list)):
- doc = frappe.get_doc("Patient Appointment", appointment_list[i][0])
- message = frappe.db.get_value("Healthcare Settings", None, "app_rem_msg")
+ for appointment in appointment_list:
+ doc = frappe.get_doc('Patient Appointment', appointment.name)
+ message = frappe.db.get_single_value('Healthcare Settings', 'appointment_reminder_msg')
send_message(doc, message)
- frappe.db.set_value("Patient Appointment", doc.name, "reminded",1)
-
+ frappe.db.set_value('Patient Appointment', doc.name, 'reminded', 1)
def send_message(doc, message):
- patient = frappe.get_doc("Patient", doc.patient)
+ patient = frappe.get_doc('Patient', doc.patient)
if patient.mobile:
- context = {"doc": doc, "alert": doc, "comments": None}
- if doc.get("_comments"):
- context["comments"] = json.loads(doc.get("_comments"))
+ context = {'doc': doc, 'alert': doc, 'comments': None}
+ if doc.get('_comments'):
+ context['comments'] = json.loads(doc.get('_comments'))
# jinja to string convertion happens here
message = frappe.render_template(message, context)
@@ -359,7 +387,7 @@
:param filters: Filters (JSON).
"""
from frappe.desk.calendar import get_event_conditions
- conditions = get_event_conditions("Patient Appointment", filters)
+ conditions = get_event_conditions('Patient Appointment', filters)
data = frappe.db.sql("""
select
@@ -381,10 +409,21 @@
return data
+
@frappe.whitelist()
def get_procedure_prescribed(patient):
return frappe.db.sql("""select pp.name, pp.procedure, pp.parent, ct.practitioner,
ct.encounter_date, pp.practitioner, pp.date, pp.department
from `tabPatient Encounter` ct, `tabProcedure Prescription` pp
where ct.patient=%(patient)s and pp.parent=ct.name and pp.appointment_booked=0
- order by ct.creation desc""", {"patient": patient})
+ order by ct.creation desc""", {'patient': patient})
+
+
+def update_appointment_status():
+ # update the status of appointments daily
+ appointments = frappe.get_all('Patient Appointment', {
+ 'status': ('not in', ['Closed', 'Cancelled'])
+ }, as_dict=1)
+
+ for appointment in appointments:
+ frappe.get_doc('Patient Appointment', appointment.name).set_status()
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment_list.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment_list.js
index 701cb69..721887b 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment_list.js
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment_list.js
@@ -3,4 +3,14 @@
*/
frappe.listview_settings['Patient Appointment'] = {
filters: [["status", "=", "Open"]],
+ get_indicator: function(doc) {
+ var colors = {
+ "Open": "orange",
+ "Scheduled": "yellow",
+ "Closed": "green",
+ "Cancelled": "red",
+ "Expired": "grey"
+ };
+ return [__(doc.status), colors[doc.status], "status,=," + doc.status];
+ }
};
diff --git a/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.py
index 3536a5f..7075af5 100644
--- a/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.py
+++ b/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.py
@@ -3,8 +3,144 @@
# See license.txt
from __future__ import unicode_literals
import unittest
-
-# test_records = frappe.get_test_records('Patient Appointment')
+import frappe
+from erpnext.healthcare.doctype.patient_appointment.patient_appointment import update_status
+from frappe.utils import nowdate, add_days
+from frappe.utils.make_random import get_random
class TestPatientAppointment(unittest.TestCase):
- pass
+ def setUp(self):
+ frappe.db.sql("""delete from `tabPatient Appointment`""")
+ frappe.db.sql("""delete from `tabFee Validity""")
+
+ def test_status(self):
+ patient, medical_department, practitioner = create_healthcare_docs()
+ frappe.db.set_value('Healthcare Settings', None, 'automate_appointment_invoicing', 0)
+ appointment = create_appointment(patient, practitioner, nowdate())
+ self.assertEquals(appointment.status, 'Open')
+ appointment = create_appointment(patient, practitioner, add_days(nowdate(), 2))
+ self.assertEquals(appointment.status, 'Scheduled')
+ create_encounter(appointment)
+ self.assertEquals(frappe.db.get_value('Patient Appointment', appointment.name, 'status'), 'Closed')
+
+ def test_invoicing(self):
+ patient, medical_department, practitioner = create_healthcare_docs()
+ frappe.db.set_value('Healthcare Settings', None, 'enable_free_follow_ups', 0)
+ frappe.db.set_value('Healthcare Settings', None, 'automate_appointment_invoicing', 0)
+ appointment = create_appointment(patient, practitioner, nowdate())
+ self.assertEqual(frappe.db.get_value('Patient Appointment', appointment.name, 'invoiced'), 0)
+
+ frappe.db.set_value('Healthcare Settings', None, 'automate_appointment_invoicing', 1)
+ appointment = create_appointment(patient, practitioner, add_days(nowdate(), 2), invoice=1)
+ self.assertEqual(frappe.db.get_value('Patient Appointment', appointment.name, 'invoiced'), 1)
+ self.assertTrue(frappe.db.get_value('Patient Appointment', appointment.name, 'ref_sales_invoice'))
+
+ def test_appointment_cancel(self):
+ patient, medical_department, practitioner = create_healthcare_docs()
+ frappe.db.set_value('Healthcare Settings', None, 'enable_free_follow_ups', 1)
+ appointment = create_appointment(patient, practitioner, nowdate())
+ fee_validity = frappe.db.get_value('Fee Validity Reference', {'appointment': appointment.name}, 'parent')
+ # fee validity created
+ self.assertTrue(fee_validity)
+
+ visited = frappe.db.get_value('Fee Validity', fee_validity, 'visited')
+ update_status(appointment.name, 'Cancelled')
+ # check fee validity updated
+ self.assertEqual(frappe.db.get_value('Fee Validity', fee_validity, 'visited'), visited - 1)
+
+ frappe.db.set_value('Healthcare Settings', None, 'enable_free_follow_ups', 0)
+ frappe.db.set_value('Healthcare Settings', None, 'automate_appointment_invoicing', 1)
+ appointment = create_appointment(patient, practitioner, nowdate(), invoice=1)
+ update_status(appointment.name, 'Cancelled')
+ # check invoice cancelled
+ sales_invoice = frappe.db.get_value('Patient Appointment', appointment.name, 'ref_sales_invoice')
+ self.assertEqual(frappe.db.get_value('Sales Invoice', sales_invoice, 'status'), 'Cancelled')
+
+
+def create_healthcare_docs():
+ patient = create_patient()
+ practitioner = frappe.db.exists('Healthcare Practitioner', '_Test Healthcare Practitioner')
+ medical_department = frappe.db.exists('Medical Department', '_Test Medical Department')
+
+ if not medical_department:
+ medical_department = frappe.new_doc('Medical Department')
+ medical_department.department = '_Test Medical Department'
+ medical_department.save(ignore_permissions=True)
+ medical_department = medical_department.name
+
+ if not practitioner:
+ practitioner = frappe.new_doc('Healthcare Practitioner')
+ practitioner.first_name = '_Test Healthcare Practitioner'
+ practitioner.gender = 'Female'
+ practitioner.department = medical_department
+ practitioner.op_consulting_charge = 500
+ practitioner.inpatient_visit_charge = 500
+ practitioner.save(ignore_permissions=True)
+ practitioner = practitioner.name
+
+ return patient, medical_department, practitioner
+
+def create_patient():
+ patient = frappe.db.exists('Patient', '_Test Patient')
+ if not patient:
+ patient = frappe.new_doc('Patient')
+ patient.first_name = '_Test Patient'
+ patient.sex = 'Female'
+ patient.save(ignore_permissions=True)
+ patient = patient.name
+ return patient
+
+def create_encounter(appointment=None):
+ encounter = frappe.new_doc('Patient Encounter')
+ if appointment:
+ encounter.appointment = appointment.name
+ encounter.patient = appointment.patient
+ encounter.practitioner = appointment.practitioner
+ encounter.encounter_date = appointment.appointment_date
+ encounter.encounter_time = appointment.appointment_time
+ encounter.save()
+ encounter.submit()
+ return encounter
+
+def create_appointment(patient, practitioner, appointment_date, invoice=0, procedure_template=0):
+ item = create_healthcare_service_items()
+ frappe.db.set_value('Healthcare Settings', None, 'inpatient_visit_charge_item', item)
+ frappe.db.set_value('Healthcare Settings', None, 'op_consulting_charge_item', item)
+ appointment = frappe.new_doc('Patient Appointment')
+ appointment.patient = patient
+ appointment.practitioner = practitioner
+ appointment.department = '_Test Medical Department'
+ appointment.appointment_date = appointment_date
+ appointment.company = '_Test Company'
+ appointment.duration = 15
+ if invoice:
+ appointment.mode_of_payment = 'Cash'
+ appointment.paid_amount = 500
+ if procedure_template:
+ appointment.procedure_template = create_clinical_procedure_template().get('name')
+ appointment.save(ignore_permissions=True)
+ return appointment
+
+def create_healthcare_service_items():
+ if frappe.db.exists('Item', 'HLC-SI-001'):
+ return 'HLC-SI-001'
+ item = frappe.new_doc('Item')
+ item.item_code = 'HLC-SI-001'
+ item.item_name = 'Consulting Charges'
+ item.item_group = 'Services'
+ item.is_stock_item = 0
+ item.save()
+ return item.name
+
+def create_clinical_procedure_template():
+ if frappe.db.exists('Clinical Procedure Template', 'Knee Surgery and Rehab'):
+ return frappe.get_doc('Clinical Procedure Template', 'Knee Surgery and Rehab')
+ template = frappe.new_doc('Clinical Procedure Template')
+ template.template = 'Knee Surgery and Rehab'
+ template.item_code = 'Knee Surgery and Rehab'
+ template.item_group = 'Services'
+ template.is_billable = 1
+ template.description = 'Knee Surgery and Rehab'
+ template.rate = 50000
+ template.save()
+ return template
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
index 088bc81..83c5d2b 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
@@ -19,297 +19,237 @@
refresh: function(frm) {
refresh_field('drug_prescription');
refresh_field('lab_test_prescription');
- if (!frm.doc.__islocal){
- frappe.call({
- method: 'frappe.client.get_value',
- args: {
- doctype: 'Patient',
- fieldname: 'inpatient_status',
- filters: {name: frm.doc.patient}
- },
- callback: function(data) {
- if(data.message && data.message.inpatient_status == "Admission Scheduled" || data.message.inpatient_status == "Admitted"){
- frm.add_custom_button(__('Schedule Discharge'), function() {
- schedule_discharge(frm);
- });
- }
- else if(data.message.inpatient_status != "Discharge Scheduled"){
- frm.add_custom_button(__('Schedule Admission'), function() {
- schedule_inpatient(frm);
- });
- }
- }
- });
- }
- frm.add_custom_button(__('Patient History'), function() {
- if (frm.doc.patient) {
- frappe.route_options = {"patient": frm.doc.patient};
- frappe.set_route("patient_history");
- } else {
- frappe.msgprint(__("Please select Patient"));
+
+ if (!frm.doc.__islocal) {
+
+ if (frm.doc.inpatient_status == 'Admission Scheduled' || frm.doc.inpatient_status == 'Admitted') {
+ frm.add_custom_button(__('Schedule Discharge'), function() {
+ schedule_discharge(frm);
+ });
+ } else if (frm.doc.inpatient_status != 'Discharge Scheduled') {
+ frm.add_custom_button(__('Schedule Admission'), function() {
+ schedule_inpatient(frm);
+ });
}
- },"View");
- frm.add_custom_button(__('Vital Signs'), function() {
- btn_create_vital_signs(frm);
- },"Create");
- frm.add_custom_button(__('Medical Record'), function() {
- create_medical_record(frm);
- },"Create");
- frm.add_custom_button(__("Procedure"),function(){
- btn_create_procedure(frm);
- },"Create");
+ frm.add_custom_button(__('Patient History'), function() {
+ if (frm.doc.patient) {
+ frappe.route_options = {'patient': frm.doc.patient};
+ frappe.set_route('patient_history');
+ } else {
+ frappe.msgprint(__('Please select Patient'));
+ }
+ },'View');
- frm.set_query("patient", function () {
+ frm.add_custom_button(__('Vital Signs'), function() {
+ create_vital_signs(frm);
+ },'Create');
+
+ frm.add_custom_button(__('Medical Record'), function() {
+ create_medical_record(frm);
+ },'Create');
+
+ frm.add_custom_button(__('Clinical Procedure'), function() {
+ create_procedure(frm);
+ },'Create');
+
+ }
+
+ frm.set_query('patient', function() {
return {
- filters: {"disabled": 0}
+ filters: {'status': 'Active'}
};
});
- frm.set_query("drug_code", "drug_prescription", function() {
+
+ frm.set_query('drug_code', 'drug_prescription', function() {
return {
filters: {
- is_stock_item:'1'
+ is_stock_item: 1
}
};
});
- frm.set_query("lab_test_code", "lab_test_prescription", function() {
+
+ frm.set_query('lab_test_code', 'lab_test_prescription', function() {
return {
filters: {
- is_billable:'1'
+ is_billable: 1
}
};
});
- frm.set_query("medical_code", "codification_table", function() {
- return {
- filters: {
- medical_code_standard: frappe.defaults.get_default("default_medical_code_standard")
- }
- };
- });
- frm.set_query("appointment", function() {
+
+ frm.set_query('appointment', function() {
return {
filters: {
// Scheduled filter for demo ...
- status:['in',["Open","Scheduled"]]
+ status:['in',['Open','Scheduled']]
}
};
});
- frm.set_df_property("appointment", "read_only", frm.doc.__islocal ? 0:1);
- frm.set_df_property("patient", "read_only", frm.doc.__islocal ? 0:1);
- frm.set_df_property("patient_age", "read_only", frm.doc.__islocal ? 0:1);
- frm.set_df_property("patient_sex", "read_only", frm.doc.__islocal ? 0:1);
- frm.set_df_property("type", "read_only", frm.doc.__islocal ? 0:1);
- frm.set_df_property("practitioner", "read_only", frm.doc.__islocal ? 0:1);
- frm.set_df_property("visit_department", "read_only", frm.doc.__islocal ? 0:1);
- frm.set_df_property("encounter_date", "read_only", frm.doc.__islocal ? 0:1);
- frm.set_df_property("encounter_time", "read_only", frm.doc.__islocal ? 0:1);
- }
-});
-var schedule_inpatient = function(frm) {
- frappe.call({
- method: "erpnext.healthcare.doctype.inpatient_record.inpatient_record.schedule_inpatient",
- args: {patient: frm.doc.patient, encounter_id: frm.doc.name, practitioner: frm.doc.practitioner},
- callback: function(data) {
- if(!data.exc){
- frm.reload_doc();
- }
- },
- freeze: true,
- freeze_message: "Process Inpatient Scheduling"
- });
-};
+ frm.set_df_property('patient', 'read_only', frm.doc.appointment ? 1 : 0);
+ },
-var schedule_discharge = function(frm) {
- frappe.call({
- method: "erpnext.healthcare.doctype.inpatient_record.inpatient_record.schedule_discharge",
- args: {patient: frm.doc.patient, encounter_id: frm.doc.name, practitioner: frm.doc.practitioner},
- callback: function(data) {
- if(!data.exc){
- frm.reload_doc();
- }
- },
- freeze: true,
- freeze_message: "Process Discharge"
- });
-};
+ appointment: function(frm) {
+ frm.events.set_appointment_fields(frm);
+ },
-var create_medical_record = function (frm) {
- if(!frm.doc.patient){
- frappe.throw(__("Please select patient"));
- }
- frappe.route_options = {
- "patient": frm.doc.patient,
- "status": "Open",
- "reference_doctype": "Patient Medical Record",
- "reference_owner": frm.doc.owner
- };
- frappe.new_doc("Patient Medical Record");
-};
+ patient: function(frm) {
+ frm.events.set_patient_info(frm);
+ },
-var btn_create_vital_signs = function (frm) {
- if(!frm.doc.patient){
- frappe.throw(__("Please select patient"));
- }
- frappe.route_options = {
- "patient": frm.doc.patient,
- "appointment": frm.doc.appointment
- };
- frappe.new_doc("Vital Signs");
-};
-
-var btn_create_procedure = function (frm) {
- if(!frm.doc.patient){
- frappe.throw(__("Please select patient"));
- }
- frappe.route_options = {
- "patient": frm.doc.patient,
- "medical_department": frm.doc.visit_department
- };
- frappe.new_doc("Clinical Procedure");
-};
-
-frappe.ui.form.on("Patient Encounter", "appointment", function(frm){
- if(frm.doc.appointment){
- frappe.call({
- "method": "frappe.client.get",
- args: {
- doctype: "Patient Appointment",
- name: frm.doc.appointment
- },
- callback: function (data) {
- frappe.model.set_value(frm.doctype,frm.docname, "patient", data.message.patient);
- frappe.model.set_value(frm.doctype,frm.docname, "type", data.message.appointment_type);
- frappe.model.set_value(frm.doctype,frm.docname, "practitioner", data.message.practitioner);
- frappe.model.set_value(frm.doctype,frm.docname, "invoiced", data.message.invoiced);
- }
- });
- }
- else{
- frappe.model.set_value(frm.doctype,frm.docname, "patient", "");
- frappe.model.set_value(frm.doctype,frm.docname, "type", "");
- frappe.model.set_value(frm.doctype,frm.docname, "practitioner", "");
- frappe.model.set_value(frm.doctype,frm.docname, "invoiced", 0);
- }
-});
-
-frappe.ui.form.on("Patient Encounter", "practitioner", function(frm) {
- if(frm.doc.practitioner){
- frappe.call({
- "method": "frappe.client.get",
- args: {
- doctype: "Healthcare Practitioner",
- name: frm.doc.practitioner
- },
- callback: function (data) {
- frappe.model.set_value(frm.doctype,frm.docname, "visit_department",data.message.department);
- }
- });
- }
-});
-
-frappe.ui.form.on("Patient Encounter", "symptoms_select", function(frm) {
- if(frm.doc.symptoms_select){
- var symptoms = null;
- if(frm.doc.symptoms)
- symptoms = frm.doc.symptoms + "\n" +frm.doc.symptoms_select;
- else
- symptoms = frm.doc.symptoms_select;
- frappe.model.set_value(frm.doctype,frm.docname, "symptoms", symptoms);
- frappe.model.set_value(frm.doctype,frm.docname, "symptoms_select", null);
- }
-});
-frappe.ui.form.on("Patient Encounter", "diagnosis_select", function(frm) {
- if(frm.doc.diagnosis_select){
- var diagnosis = null;
- if(frm.doc.diagnosis)
- diagnosis = frm.doc.diagnosis + "\n" +frm.doc.diagnosis_select;
- else
- diagnosis = frm.doc.diagnosis_select;
- frappe.model.set_value(frm.doctype,frm.docname, "diagnosis", diagnosis);
- frappe.model.set_value(frm.doctype,frm.docname, "diagnosis_select", null);
- }
-});
-
-frappe.ui.form.on("Patient Encounter", "patient", function(frm) {
- if(frm.doc.patient){
- frappe.call({
- "method": "erpnext.healthcare.doctype.patient.patient.get_patient_detail",
- args: {
- patient: frm.doc.patient
- },
- callback: function (data) {
- var age = "";
- if(data.message.dob){
- age = calculate_age(data.message.dob);
- }
- frappe.model.set_value(frm.doctype,frm.docname, "patient_age", age);
- frappe.model.set_value(frm.doctype,frm.docname, "patient_sex", data.message.sex);
- }
- });
- }
-});
-
-frappe.ui.form.on("Drug Prescription", {
- drug_code: function(frm, cdt, cdn) {
- var child = locals[cdt][cdn];
- if(child.drug_code){
+ set_appointment_fields: function(frm) {
+ if (frm.doc.appointment) {
frappe.call({
- "method": "frappe.client.get",
+ method: 'frappe.client.get',
args: {
- doctype: "Item",
- name: child.drug_code,
+ doctype: 'Patient Appointment',
+ name: frm.doc.appointment
},
- callback: function (data) {
- frappe.model.set_value(cdt, cdn, 'drug_name',data.message.item_name);
+ callback: function(data) {
+ let values = {
+ 'patient':data.message.patient,
+ 'type': data.message.appointment_type,
+ 'practitioner': data.message.practitioner,
+ 'invoiced': data.message.invoiced
+ };
+ frm.set_value(values);
}
});
}
+ else {
+ let values = {
+ 'patient': '',
+ 'patient_name': '',
+ 'type': '',
+ 'practitioner': '',
+ 'invoiced': 0,
+ 'patient_sex': '',
+ 'patient_age': '',
+ 'inpatient_record': '',
+ 'inpatient_status': ''
+ };
+ frm.set_value(values);
+ }
},
+
+ set_patient_info: function(frm) {
+ if (frm.doc.patient) {
+ frappe.call({
+ method: 'erpnext.healthcare.doctype.patient.patient.get_patient_detail',
+ args: {
+ patient: frm.doc.patient
+ },
+ callback: function(data) {
+ let age = '';
+ if (data.message.dob) {
+ age = calculate_age(data.message.dob);
+ }
+ frappe.model.set_value(frm.doctype, frm.docname, 'patient_age', age);
+ frappe.model.set_value(frm.doctype, frm.docname, 'patient_sex', data.message.sex);
+ if (data.message.inpatient_record) {
+ frappe.model.set_value(frm.doctype, frm.docname, 'inpatient_record', data.message.inpatient_record);
+ frappe.model.set_value(frm.doctype, frm.docname, 'inpatient_status', data.message.inpatient_status);
+ }
+ }
+ });
+ } else {
+ frappe.model.set_value(frm.doctype, frm.docname, 'patient_sex', '');
+ frappe.model.set_value(frm.doctype, frm.docname, 'patient_age', '');
+ frappe.model.set_value(frm.doctype, frm.docname, 'inpatient_record', '');
+ frappe.model.set_value(frm.doctype, frm.docname, 'inpatient_status', '');
+ }
+ }
+});
+
+let schedule_inpatient = function(frm) {
+ frappe.call({
+ method: 'erpnext.healthcare.doctype.inpatient_record.inpatient_record.schedule_inpatient',
+ args: {patient: frm.doc.patient, encounter_id: frm.doc.name, practitioner: frm.doc.practitioner},
+ callback: function(data) {
+ if (!data.exc) {
+ frm.reload_doc();
+ }
+ },
+ freeze: true,
+ freeze_message: __('Process Inpatient Scheduling')
+ });
+};
+
+let schedule_discharge = function(frm) {
+ frappe.call({
+ method: 'erpnext.healthcare.doctype.inpatient_record.inpatient_record.schedule_discharge',
+ args: {patient: frm.doc.patient, encounter_id: frm.doc.name, practitioner: frm.doc.practitioner},
+ callback: function(data) {
+ if (!data.exc) {
+ frm.reload_doc();
+ }
+ },
+ freeze: true,
+ freeze_message: 'Process Discharge'
+ });
+};
+
+let create_medical_record = function (frm) {
+ if (!frm.doc.patient) {
+ frappe.throw(__('Please select patient'));
+ }
+ frappe.route_options = {
+ 'patient': frm.doc.patient,
+ 'status': 'Open',
+ 'reference_doctype': 'Patient Medical Record',
+ 'reference_owner': frm.doc.owner
+ };
+ frappe.new_doc('Patient Medical Record');
+};
+
+let create_vital_signs = function (frm) {
+ if (!frm.doc.patient) {
+ frappe.throw(__('Please select patient'));
+ }
+ frappe.route_options = {
+ 'patient': frm.doc.patient,
+ 'appointment': frm.doc.appointment,
+ 'encounter': frm.doc.name
+ };
+ frappe.new_doc('Vital Signs');
+};
+
+let create_procedure = function (frm) {
+ if (!frm.doc.patient) {
+ frappe.throw(__('Please select patient'));
+ }
+ frappe.route_options = {
+ 'patient': frm.doc.patient,
+ 'medical_department': frm.doc.medical_department
+ };
+ frappe.new_doc('Clinical Procedure');
+};
+
+frappe.ui.form.on('Drug Prescription', {
dosage: function(frm, cdt, cdn){
frappe.model.set_value(cdt, cdn, 'update_schedule', 1);
- var child = locals[cdt][cdn];
- if(child.dosage){
- frappe.model.set_value(cdt, cdn, 'in_every', 'Day');
+ let child = locals[cdt][cdn];
+ if (child.dosage) {
+ frappe.model.set_value(cdt, cdn, 'interval_uom', 'Day');
frappe.model.set_value(cdt, cdn, 'interval', 1);
}
},
- period: function(frm, cdt, cdn){
+ period: function(frm, cdt, cdn) {
frappe.model.set_value(cdt, cdn, 'update_schedule', 1);
},
- in_every: function(frm, cdt, cdn){
+ interval_uom: function(frm, cdt, cdn) {
frappe.model.set_value(cdt, cdn, 'update_schedule', 1);
- var child = locals[cdt][cdn];
- if(child.in_every == "Hour"){
+ let child = locals[cdt][cdn];
+ if (child.interval_uom == 'Hour') {
frappe.model.set_value(cdt, cdn, 'dosage', null);
}
}
});
-frappe.ui.form.on("Procedure Prescription", {
- procedure: function(frm, cdt, cdn) {
- var child = locals[cdt][cdn];
- if(child.procedure){
- frappe.call({
- "method": "frappe.client.get_value",
- args: {
- doctype: "Clinical Procedure Template",
- fieldname: "medical_department",
- filters: {name: child.procedure}
- },
- callback: function (data) {
- frappe.model.set_value(cdt, cdn, 'department',data.message.medical_department);
- }
- });
- }
- }
-});
-
-
-var calculate_age = function(birth) {
- var ageMS = Date.parse(Date()) - Date.parse(birth);
- var age = new Date();
+let calculate_age = function(birth) {
+ let ageMS = Date.parse(Date()) - Date.parse(birth);
+ let age = new Date();
age.setTime(ageMS);
- var years = age.getFullYear() - 1970;
- return years + " Year(s) " + age.getMonth() + " Month(s) " + age.getDate() + " Day(s)";
+ let years = age.getFullYear() - 1970;
+ return years + ' Year(s) ' + age.getMonth() + ' Month(s) ' + age.getDate() + ' Day(s)';
};
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
index 91c9d7b..d00e7bc 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
@@ -1,1183 +1,324 @@
{
- "allow_copy": 1,
- "allow_guest_to_view": 0,
- "allow_import": 1,
- "allow_rename": 0,
- "autoname": "naming_series:",
- "beta": 1,
- "creation": "2016-04-21 10:53:44.637684",
- "custom": 0,
- "default_print_format": "",
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Document",
- "editable_grid": 1,
+ "actions": [],
+ "allow_copy": 1,
+ "allow_import": 1,
+ "autoname": "naming_series:",
+ "beta": 1,
+ "creation": "2016-04-21 10:53:44.637684",
+ "doctype": "DocType",
+ "document_type": "Document",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "naming_series",
+ "appointment",
+ "appointment_type",
+ "patient",
+ "patient_name",
+ "patient_sex",
+ "patient_age",
+ "company",
+ "column_break_6",
+ "practitioner",
+ "medical_department",
+ "encounter_date",
+ "encounter_time",
+ "invoiced",
+ "section_break_1",
+ "inpatient_record",
+ "column_break_17",
+ "inpatient_status",
+ "sb_symptoms",
+ "symptoms",
+ "symptoms_in_print",
+ "physical_examination",
+ "diagnosis",
+ "diagnosis_in_print",
+ "codification",
+ "codification_table",
+ "sb_drug_prescription",
+ "drug_prescription",
+ "sb_test_prescription",
+ "lab_test_prescription",
+ "sb_procedures",
+ "procedure_prescription",
+ "encounter_comment",
+ "amended_from"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "patient.inpatient_record",
- "fieldname": "inpatient_record",
- "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": "Inpatient Record",
- "length": 0,
- "no_copy": 0,
- "options": "Inpatient Record",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "inpatient_record",
+ "fieldtype": "Link",
+ "label": "Inpatient Record",
+ "options": "Inpatient Record",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "section_break_1",
- "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,
- "translatable": 0,
- "unique": 0
- },
+ "collapsible": 1,
+ "fieldname": "section_break_1",
+ "fieldtype": "Section Break",
+ "label": "Inpatient Details"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "fieldname": "naming_series",
- "fieldtype": "Select",
- "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": "Series",
- "length": 0,
- "no_copy": 0,
- "options": "HLC-ENC-.YYYY.-",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "naming_series",
+ "fieldtype": "Select",
+ "label": "Series",
+ "no_copy": 1,
+ "options": "HLC-ENC-.YYYY.-",
+ "set_only_once": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "appointment",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Appointment",
- "length": 0,
- "no_copy": 0,
- "options": "Patient Appointment",
- "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": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "appointment",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "label": "Appointment",
+ "options": "Patient Appointment",
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "type",
- "fieldtype": "Link",
- "hidden": 1,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Type",
- "length": 0,
- "no_copy": 1,
- "options": "Appointment Type",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "inpatient_record.patient",
+ "fieldname": "patient",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Patient",
+ "options": "Patient",
+ "reqd": 1,
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "inpatient_record.patient",
- "fieldname": "patient",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Patient",
- "length": 0,
- "no_copy": 0,
- "options": "Patient",
- "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": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "patient.patient_name",
+ "fieldname": "patient_name",
+ "fieldtype": "Data",
+ "label": "Patient Name",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "fetch_from": "patient.patient_name",
- "fieldname": "patient_name",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Patient Name",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "patient_age",
+ "fieldtype": "Data",
+ "label": "Age",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "patient_age",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Age",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "patient_sex",
+ "fieldtype": "Link",
+ "label": "Gender",
+ "options": "Gender",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "patient_sex",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Gender",
- "length": 0,
- "no_copy": 0,
- "options": "\nMale\nFemale\nOther",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "label": "Company",
+ "options": "Company"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "company",
- "fieldtype": "Link",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Company",
- "length": 0,
- "no_copy": 0,
- "options": "Company",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_6",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_6",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "practitioner",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Healthcare Practitioner",
+ "options": "Healthcare Practitioner",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "practitioner",
- "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": 1,
- "label": "Healthcare Practitioner",
- "length": 0,
- "no_copy": 0,
- "options": "Healthcare Practitioner",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "Today",
+ "fieldname": "encounter_date",
+ "fieldtype": "Date",
+ "in_list_view": 1,
+ "label": "Encounter Date",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "visit_department",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Department",
- "length": 0,
- "no_copy": 0,
- "options": "Medical Department",
- "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": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "encounter_time",
+ "fieldtype": "Time",
+ "label": "Encounter Time",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "Today",
- "fieldname": "encounter_date",
- "fieldtype": "Date",
- "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": "Encounter Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "invoiced",
+ "fieldtype": "Check",
+ "label": "Invoiced",
+ "no_copy": 1,
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "fieldname": "encounter_time",
- "fieldtype": "Time",
- "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": "Encounter Time",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "sb_symptoms",
+ "fieldtype": "Section Break",
+ "label": "Encounter Impression"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "invoiced",
- "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": "Invoiced",
- "length": 0,
- "no_copy": 1,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "symptoms",
+ "fieldtype": "Table MultiSelect",
+ "ignore_xss_filter": 1,
+ "label": "Symptoms",
+ "no_copy": 1,
+ "options": "Patient Encounter Symptom"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 1,
- "columns": 0,
- "fieldname": "sb_symptoms",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Encounter Impression",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "depends_on": "eval: doc.symptoms != ''",
+ "fieldname": "symptoms_in_print",
+ "fieldtype": "Check",
+ "label": "In print",
+ "no_copy": 1,
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "symptoms_select",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Complaints",
- "length": 0,
- "no_copy": 1,
- "options": "Complaint",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "physical_examination",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "symptoms",
- "fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "diagnosis",
+ "fieldtype": "Table MultiSelect",
+ "ignore_xss_filter": 1,
+ "label": "Diagnosis",
+ "no_copy": 1,
+ "options": "Patient Encounter Diagnosis"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "symptoms_in_print",
- "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": "In print",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "1",
+ "depends_on": "eval: doc.diagnosis != ''",
+ "fieldname": "diagnosis_in_print",
+ "fieldtype": "Check",
+ "label": "In print",
+ "no_copy": 1,
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "physical_examination",
- "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,
- "label": "",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "collapsible": 1,
+ "fieldname": "codification",
+ "fieldtype": "Section Break",
+ "label": "Medical Coding"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "diagnosis_select",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Diagnosis",
- "length": 0,
- "no_copy": 1,
- "options": "Diagnosis",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "codification_table",
+ "fieldtype": "Table",
+ "label": "Medical Coding",
+ "options": "Codification Table"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "diagnosis",
- "fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "sb_drug_prescription",
+ "fieldtype": "Section Break",
+ "label": "Medication"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "1",
- "depends_on": "",
- "fieldname": "diagnosis_in_print",
- "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": "In print",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "drug_prescription",
+ "fieldtype": "Table",
+ "label": "Drug Prescription",
+ "options": "Drug Prescription"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 1,
- "columns": 0,
- "fieldname": "codification",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Medical Coding",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "sb_test_prescription",
+ "fieldtype": "Section Break",
+ "label": "Investigation"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "codification_table",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Medical Coding",
- "length": 0,
- "no_copy": 0,
- "options": "Codification Table",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "lab_test_prescription",
+ "fieldtype": "Table",
+ "label": "Lab Prescription",
+ "options": "Lab Prescription"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sb_drug_prescription",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Medication",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "sb_procedures",
+ "fieldtype": "Section Break",
+ "label": "Procedures"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "drug_prescription",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Medication",
- "length": 0,
- "no_copy": 0,
- "options": "Drug Prescription",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "procedure_prescription",
+ "fieldtype": "Table",
+ "label": "Procedure Prescription",
+ "no_copy": 1,
+ "options": "Procedure Prescription"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sb_test_prescription",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Investigations",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "encounter_comment",
+ "fieldtype": "Small Text",
+ "ignore_xss_filter": 1,
+ "label": "Review Details",
+ "no_copy": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "lab_test_prescription",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Investigations",
- "length": 0,
- "no_copy": 0,
- "options": "Lab Prescription",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "label": "Amended From",
+ "no_copy": 1,
+ "options": "Patient Encounter",
+ "print_hide": 1,
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sb_procedures",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Procedures",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "appointment_type",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "label": "Appointment Type",
+ "no_copy": 1,
+ "options": "Appointment Type",
+ "print_hide": 1,
+ "read_only": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "procedure_prescription",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Procedures",
- "length": 0,
- "no_copy": 1,
- "options": "Procedure Prescription",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "practitioner.department",
+ "fieldname": "medical_department",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Department",
+ "options": "Medical Department",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "encounter_comment",
- "fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Review Details",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "inpatient_status",
+ "fieldtype": "Data",
+ "label": "Inpatient Status",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 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": "Patient Encounter",
- "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,
- "translatable": 0,
- "unique": 0
+ "fieldname": "column_break_17",
+ "fieldtype": "Column Break"
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 1,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-09-04 11:50:52.217175",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Patient Encounter",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "is_submittable": 1,
+ "links": [],
+ "modified": "2020-02-27 12:42:21.751964",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Patient Encounter",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 1,
- "cancel": 1,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Physician",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 1,
+ "amend": 1,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Physician",
+ "share": 1,
+ "submit": 1,
"write": 1
}
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "search_fields": "patient, practitioner, visit_department, encounter_date, encounter_time",
- "show_name_in_global_search": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "patient",
- "track_changes": 1,
- "track_seen": 1,
- "track_views": 0
+ ],
+ "restrict_to_domain": "Healthcare",
+ "search_fields": "patient, practitioner, medical_department, encounter_date, encounter_time",
+ "show_name_in_global_search": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "patient",
+ "track_changes": 1,
+ "track_seen": 1
}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
index fe7ac8e..ade4748 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
@@ -6,59 +6,63 @@
import frappe
from frappe.model.document import Document
from frappe.utils import cstr
+from frappe import _
class PatientEncounter(Document):
def on_update(self):
- if(self.appointment):
- frappe.db.set_value("Patient Appointment", self.appointment, "status", "Closed")
- update_encounter_to_medical_record(self)
+ if self.appointment:
+ frappe.db.set_value('Patient Appointment', self.appointment, 'status', 'Closed')
+ update_encounter_medical_record(self)
def after_insert(self):
insert_encounter_to_medical_record(self)
def on_cancel(self):
- if(self.appointment):
- frappe.db.set_value("Patient Appointment", self.appointment, "status", "Open")
+ if self.appointment:
+ frappe.db.set_value('Patient Appointment', self.appointment, 'status', 'Open')
delete_medical_record(self)
def insert_encounter_to_medical_record(doc):
subject = set_subject_field(doc)
- medical_record = frappe.new_doc("Patient Medical Record")
+ medical_record = frappe.new_doc('Patient Medical Record')
medical_record.patient = doc.patient
medical_record.subject = subject
- medical_record.status = "Open"
+ medical_record.status = 'Open'
medical_record.communication_date = doc.encounter_date
- medical_record.reference_doctype = "Patient Encounter"
+ medical_record.reference_doctype = 'Patient Encounter'
medical_record.reference_name = doc.name
medical_record.reference_owner = doc.owner
medical_record.save(ignore_permissions=True)
-def update_encounter_to_medical_record(encounter):
- medical_record_id = frappe.db.sql("select name from `tabPatient Medical Record` where reference_name=%s", (encounter.name))
+def update_encounter_medical_record(encounter):
+ medical_record_id = frappe.db.exists('Patient Medical Record', {'reference_name': encounter.name})
+
if medical_record_id and medical_record_id[0][0]:
subject = set_subject_field(encounter)
- frappe.db.set_value("Patient Medical Record", medical_record_id[0][0], "subject", subject)
+ frappe.db.set_value('Patient Medical Record', medical_record_id[0][0], 'subject', subject)
else:
insert_encounter_to_medical_record(encounter)
def delete_medical_record(encounter):
- frappe.db.sql("""delete from `tabPatient Medical Record` where reference_name = %s""", (encounter.name))
+ frappe.db.delete_doc_if_exists('Patient Medical Record', 'reference_name', encounter.name)
def set_subject_field(encounter):
- subject = encounter.practitioner+"<br/>"
- if(encounter.symptoms):
- subject += "Symptoms: "+ cstr(encounter.symptoms)+".<br/>"
+ subject = encounter.practitioner + '\n'
+ if encounter.symptoms:
+ subject += _('Symptoms: ') + cstr(encounter.symptoms) + '\n'
else:
- subject += "No Symptoms <br/>"
- if(encounter.diagnosis):
- subject += "Diagnosis: "+ cstr(encounter.diagnosis)+".<br/>"
+ subject += _('No Symptoms') + '\n'
+
+ if encounter.diagnosis:
+ subject += _('Diagnosis: ') + cstr(encounter.diagnosis) + '\n'
else:
- subject += "No Diagnosis <br/>"
- if(encounter.drug_prescription):
- subject +="\nDrug(s) Prescribed. "
- if(encounter.lab_test_prescription):
- subject += "\nTest(s) Prescribed."
- if(encounter.procedure_prescription):
- subject += "\nProcedure(s) Prescribed."
+ subject += _('No Diagnosis') + '\n'
+
+ if encounter.drug_prescription:
+ subject += '\n' + _('Drug(s) Prescribed.')
+ if encounter.lab_test_prescription:
+ subject += '\n' + _('Test(s) Prescribed.')
+ if encounter.procedure_prescription:
+ subject += '\n' + _('Procedure(s) Prescribed.')
return subject
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter_list.js b/erpnext/healthcare/doctype/patient_encounter/patient_encounter_list.js
index 93c02f6..d8f63bd 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter_list.js
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter_list.js
@@ -2,5 +2,5 @@
(c) ESS 2015-16
*/
frappe.listview_settings['Patient Encounter'] = {
- filters:[["docstatus","!=","1"]]
+ filters:[["docstatus","!=","2"]]
};
diff --git a/erpnext/healthcare/page/appointment_analytic/__init__.py b/erpnext/healthcare/doctype/patient_encounter_diagnosis/__init__.py
similarity index 100%
copy from erpnext/healthcare/page/appointment_analytic/__init__.py
copy to erpnext/healthcare/doctype/patient_encounter_diagnosis/__init__.py
diff --git a/erpnext/healthcare/doctype/patient_encounter_diagnosis/patient_encounter_diagnosis.json b/erpnext/healthcare/doctype/patient_encounter_diagnosis/patient_encounter_diagnosis.json
new file mode 100644
index 0000000..00ca309
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_encounter_diagnosis/patient_encounter_diagnosis.json
@@ -0,0 +1,33 @@
+{
+ "actions": [],
+ "beta": 1,
+ "creation": "2020-02-26 16:48:16.835105",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "diagnosis"
+ ],
+ "fields": [
+ {
+ "fieldname": "diagnosis",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Diagnosis",
+ "options": "Diagnosis",
+ "reqd": 1
+ }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-02-26 16:58:16.480583",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Patient Encounter Diagnosis",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_encounter_diagnosis/patient_encounter_diagnosis.py b/erpnext/healthcare/doctype/patient_encounter_diagnosis/patient_encounter_diagnosis.py
new file mode 100644
index 0000000..34b0cf8
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_encounter_diagnosis/patient_encounter_diagnosis.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class PatientEncounterDiagnosis(Document):
+ pass
diff --git a/erpnext/healthcare/page/appointment_analytic/__init__.py b/erpnext/healthcare/doctype/patient_encounter_symptom/__init__.py
similarity index 100%
copy from erpnext/healthcare/page/appointment_analytic/__init__.py
copy to erpnext/healthcare/doctype/patient_encounter_symptom/__init__.py
diff --git a/erpnext/healthcare/doctype/patient_encounter_symptom/patient_encounter_symptom.json b/erpnext/healthcare/doctype/patient_encounter_symptom/patient_encounter_symptom.json
new file mode 100644
index 0000000..bc92145
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_encounter_symptom/patient_encounter_symptom.json
@@ -0,0 +1,33 @@
+{
+ "actions": [],
+ "beta": 1,
+ "creation": "2020-02-26 16:47:00.525657",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "complaint"
+ ],
+ "fields": [
+ {
+ "fieldname": "complaint",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Complaint",
+ "options": "Complaint",
+ "reqd": 1
+ }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-02-26 16:57:37.997481",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Patient Encounter Symptom",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_encounter_symptom/patient_encounter_symptom.py b/erpnext/healthcare/doctype/patient_encounter_symptom/patient_encounter_symptom.py
new file mode 100644
index 0000000..bdb7bb2
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_encounter_symptom/patient_encounter_symptom.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class PatientEncounterSymptom(Document):
+ pass
diff --git a/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.json b/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.json
index c6a6b44..3655e24 100644
--- a/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.json
+++ b/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.json
@@ -1,457 +1,155 @@
{
- "allow_copy": 1,
- "allow_guest_to_view": 0,
- "allow_import": 1,
- "allow_rename": 0,
- "autoname": "naming_series:",
- "beta": 1,
- "creation": "2016-06-09 11:30:44.972056",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 0,
+ "actions": [],
+ "allow_copy": 1,
+ "allow_import": 1,
+ "autoname": "naming_series:",
+ "beta": 1,
+ "creation": "2016-06-09 11:30:44.972056",
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "engine": "InnoDB",
+ "field_order": [
+ "naming_series",
+ "patient",
+ "status",
+ "column_break_2",
+ "attach",
+ "section_break_4",
+ "subject",
+ "section_break_8",
+ "communication_date",
+ "reference_doctype",
+ "reference_name",
+ "column_break_9",
+ "reference_owner",
+ "user"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "fieldname": "naming_series",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Series",
- "length": 0,
- "no_copy": 0,
- "options": "HLC-PMR-.YYYY.-",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "naming_series",
+ "fieldtype": "Select",
+ "label": "Series",
+ "options": "HLC-PMR-.YYYY.-",
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "patient",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Patient",
- "length": 0,
- "no_copy": 0,
- "options": "Patient",
- "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": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "patient",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "in_list_view": 1,
+ "label": "Patient",
+ "options": "Patient",
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_2",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_2",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "attach",
- "fieldtype": "Attach",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "attach",
+ "fieldtype": "Attach",
+ "label": "Attach Medical Record"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "section_break_4",
- "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,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "section_break_4",
+ "fieldtype": "Section Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "subject",
- "fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Subject",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "subject",
+ "fieldtype": "Small Text",
+ "ignore_xss_filter": 1,
+ "label": "Subject"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "status",
- "fieldtype": "Select",
- "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": "Status",
- "length": 0,
- "no_copy": 0,
- "options": "Open\nClose",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "label": "Status",
+ "options": "Open\nClose",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "Today",
- "fieldname": "communication_date",
- "fieldtype": "Date",
- "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": "Datetime",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "Today",
+ "fieldname": "communication_date",
+ "fieldtype": "Date",
+ "in_list_view": 1,
+ "label": "Datetime",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "reference_doctype",
- "fieldtype": "Link",
- "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": "Reference DocType",
- "length": 0,
- "no_copy": 0,
- "options": "DocType",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "reference_doctype",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Reference DocType",
+ "options": "DocType",
+ "read_only": 1,
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "reference_name",
- "fieldtype": "Dynamic Link",
- "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": "Reference Name",
- "length": 0,
- "no_copy": 0,
- "options": "reference_doctype",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "reference_name",
+ "fieldtype": "Dynamic Link",
+ "in_list_view": 1,
+ "label": "Reference Name",
+ "options": "reference_doctype",
+ "read_only": 1,
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "reference_name.owner",
- "fieldname": "reference_owner",
- "fieldtype": "Data",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Reference Owner",
- "length": 0,
- "no_copy": 1,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "reference_name.owner",
+ "fieldname": "reference_owner",
+ "fieldtype": "Data",
+ "label": "Reference Owner",
+ "no_copy": 1,
+ "print_hide": 1,
+ "read_only": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "__user",
- "fieldname": "user",
- "fieldtype": "Link",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "User",
- "length": 0,
- "no_copy": 0,
- "options": "User",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "default": "__user",
+ "fieldname": "user",
+ "fieldtype": "Link",
+ "label": "User",
+ "options": "User",
+ "print_hide": 1,
+ "read_only": 1,
+ "report_hide": 1
+ },
+ {
+ "fieldname": "column_break_9",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "section_break_8",
+ "fieldtype": "Section Break"
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 1,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-08-21 14:44:37.927284",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Patient Medical Record",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "in_create": 1,
+ "links": [],
+ "modified": "2020-03-23 19:26:59.308383",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Patient Medical Record",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Physician",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Physician",
+ "share": 1,
"write": 1
}
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "search_fields": "patient, subject, communication_date, reference_doctype, reference_name",
- "show_name_in_global_search": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "patient",
- "track_changes": 1,
- "track_seen": 1,
- "track_views": 0
-}
+ ],
+ "restrict_to_domain": "Healthcare",
+ "search_fields": "patient, subject, communication_date, reference_doctype, reference_name",
+ "show_name_in_global_search": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "patient",
+ "track_changes": 1,
+ "track_seen": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_medical_record/test_patient_medical_record.py b/erpnext/healthcare/doctype/patient_medical_record/test_patient_medical_record.py
index 460774a..e5a5e4c 100644
--- a/erpnext/healthcare/doctype/patient_medical_record/test_patient_medical_record.py
+++ b/erpnext/healthcare/doctype/patient_medical_record/test_patient_medical_record.py
@@ -3,8 +3,86 @@
# See license.txt
from __future__ import unicode_literals
import unittest
-
-# test_records = frappe.get_test_records('Patient Medical Record')
+import frappe
+from frappe.utils import nowdate
+from erpnext.healthcare.doctype.patient_appointment.test_patient_appointment import create_encounter, create_healthcare_docs, create_appointment
class TestPatientMedicalRecord(unittest.TestCase):
- pass
+ def setUp(self):
+ frappe.db.set_value('Healthcare Settings', None, 'enable_free_follow_ups', 0)
+ frappe.db.set_value('Healthcare Settings', None, 'automate_appointment_invoicing', 1)
+
+ def test_medical_record(self):
+ patient, medical_department, practitioner = create_healthcare_docs()
+ appointment = create_appointment(patient, practitioner, nowdate(), invoice=1)
+ encounter = create_encounter(appointment)
+ # check for encounter
+ medical_rec = frappe.db.exists('Patient Medical Record', {'status': 'Open', 'reference_name': encounter.name})
+ self.assertTrue(medical_rec)
+
+ vital_signs = create_vital_signs(appointment)
+ # check for vital signs
+ medical_rec = frappe.db.exists('Patient Medical Record', {'status': 'Open', 'reference_name': vital_signs.name})
+ self.assertTrue(medical_rec)
+
+ appointment = create_appointment(patient, practitioner, nowdate(), invoice=1, procedure_template=1)
+ procedure = create_procedure(appointment)
+ procedure.start_procedure()
+ procedure.complete_procedure()
+ # check for clinical procedure
+ medical_rec = frappe.db.exists('Patient Medical Record', {'status': 'Open', 'reference_name': procedure.name})
+ self.assertTrue(medical_rec)
+
+ template = create_lab_test_template(medical_department)
+ lab_test = create_lab_test(template, patient)
+ # check for lab test
+ medical_rec = frappe.db.exists('Patient Medical Record', {'status': 'Open', 'reference_name': lab_test.name})
+ self.assertTrue(medical_rec)
+
+
+def create_procedure(appointment):
+ if appointment:
+ procedure = frappe.new_doc('Clinical Procedure')
+ procedure.procedure_template = appointment.procedure_template
+ procedure.appointment = appointment.name
+ procedure.patient = appointment.patient
+ procedure.practitioner = appointment.practitioner
+ procedure.medical_department = appointment.department
+ procedure.start_dt = appointment.appointment_date
+ procedure.start_time = appointment.appointment_time
+ procedure.save()
+ procedure.submit()
+ return procedure
+
+def create_vital_signs(appointment):
+ vital_signs = frappe.new_doc('Vital Signs')
+ vital_signs.patient = appointment.patient
+ vital_signs.signs_date = appointment.appointment_date
+ vital_signs.signs_time = appointment.appointment_time
+ vital_signs.temperature = 38.5
+ vital_signs.save()
+ vital_signs.submit()
+ return vital_signs
+
+def create_lab_test_template(medical_department):
+ if frappe.db.exists('Lab Test Template', 'Blood Test'):
+ return 'Blood Test'
+
+ template = frappe.new_doc('Lab Test Template')
+ template.lab_test_name = 'Blood Test'
+ template.lab_test_code = 'Blood Test'
+ template.lab_test_group = 'Services'
+ template.department = medical_department
+ template.is_billable = 1
+ template.lab_test_rate = 2000
+ template.save()
+ return template.name
+
+def create_lab_test(template, patient):
+ lab_test = frappe.new_doc('Lab Test')
+ lab_test.patient = patient
+ lab_test.patient_sex = frappe.db.get_value('Patient', patient, 'sex')
+ lab_test.template = template
+ lab_test.save()
+ lab_test.submit()
+ return lab_test
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_relation/patient_relation.json b/erpnext/healthcare/doctype/patient_relation/patient_relation.json
index 209a374..376f7f7 100644
--- a/erpnext/healthcare/doctype/patient_relation/patient_relation.json
+++ b/erpnext/healthcare/doctype/patient_relation/patient_relation.json
@@ -1,134 +1,52 @@
{
- "allow_copy": 1,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 1,
- "creation": "2017-04-26 15:40:11.561855",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "actions": [],
+ "allow_copy": 1,
+ "beta": 1,
+ "creation": "2017-04-26 15:40:11.561855",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "patient",
+ "relation",
+ "description"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "relation",
- "fieldtype": "Select",
- "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": "Relation",
- "length": 0,
- "no_copy": 0,
- "options": "\nFather\nMother\nSpouse\nSiblings\nFamily",
- "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": 1,
- "set_only_once": 0,
- "unique": 0
- },
+ "fieldname": "relation",
+ "fieldtype": "Select",
+ "in_list_view": 1,
+ "label": "Relation",
+ "options": "\nFather\nMother\nSpouse\nSiblings\nFamily\nOther",
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "patient",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Patient",
- "length": 0,
- "no_copy": 0,
- "options": "Patient",
- "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
- },
+ "fieldname": "patient",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "in_list_view": 1,
+ "label": "Patient",
+ "options": "Patient",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "description",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Description",
- "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
+ "fieldname": "description",
+ "fieldtype": "Small Text",
+ "ignore_xss_filter": 1,
+ "label": "Description"
}
- ],
- "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-10-04 16:12:45.485333",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Patient Relation",
- "name_case": "",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1,
- "track_seen": 0
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-01-29 12:45:40.081899",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Patient Relation",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "restrict_to_domain": "Healthcare",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.js b/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.js
index f247856..7cb7c4b 100644
--- a/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.js
+++ b/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.js
@@ -5,9 +5,9 @@
refresh: function(frm) {
cur_frm.fields_dict["time_slots"].grid.wrapper.find('.grid-add-row').hide();
cur_frm.fields_dict["time_slots"].grid.add_custom_button(__('Add Time Slots'), () => {
- var d = new frappe.ui.Dialog({
+ let d = new frappe.ui.Dialog({
fields: [
- {fieldname: 'days', label: __('Select Days'), fieldtype:'MultiSelect',
+ {fieldname: 'days', label: __('Select Days'), fieldtype: 'MultiSelect',
options:[
{value:'Sunday', label:__('Sunday')},
{value:'Monday', label:__('Monday')},
@@ -17,40 +17,41 @@
{value:'Friday', label:__('Friday')},
{value:'Saturday', label:__('Saturday')},
], reqd: 1},
- {fieldname: 'from_time', label:__('From'), fieldtype:'Time',
+ {fieldname: 'from_time', label: __('From'), fieldtype: 'Time',
'default': '09:00:00', reqd: 1},
- {fieldname: 'to_time', label:__('To'), fieldtype:'Time',
+ {fieldname: 'to_time', label: __('To'), fieldtype: 'Time',
'default': '12:00:00', reqd: 1},
- {fieldname: 'duration', label:__('Appointment Duration (mins)'),
+ {fieldname: 'duration', label: __('Appointment Duration (mins)'),
fieldtype:'Int', 'default': 15, reqd: 1},
],
primary_action_label: __('Add Timeslots'),
primary_action: () => {
- var values = d.get_values();
- if(values) {
+ let values = d.get_values();
+ if (values) {
let slot_added = false;
values.days.split(',').forEach(function(day){
day = $.trim(day);
- if(['Sunday', 'Monday', 'Tuesday', 'Wednesday',
+ if (['Sunday', 'Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Saturday'].includes(day)){
add_slots(day);
}
});
+
function check_overlap_or_add_slot(week_day, cur_time, end_time, add_slots_to_child){
let overlap = false;
- while(cur_time < end_time) {
+ while (cur_time < end_time) {
let add_to_child = true;
let to_time = cur_time.clone().add(values.duration, 'minutes');
- if(to_time <= end_time) {
- if(frm.doc.time_slots){
+ if (to_time <= end_time) {
+ if (frm.doc.time_slots){
frm.doc.time_slots.forEach(function(slot) {
- if(slot.day == week_day){
+ if (slot.day == week_day){
let slot_from_moment = moment(slot.from_time, 'HH:mm:ss');
let slot_to_moment = moment(slot.to_time, 'HH:mm:ss');
- if(cur_time.isSame(slot_from_moment) || cur_time.isBetween(slot_from_moment, slot_to_moment) ||
- to_time.isSame(slot_to_moment) || to_time.isBetween(slot_from_moment, slot_to_moment)){
+ if (cur_time.isSame(slot_from_moment) || cur_time.isBetween(slot_from_moment, slot_to_moment) ||
+ to_time.isSame(slot_to_moment) || to_time.isBetween(slot_from_moment, slot_to_moment)) {
overlap = true;
- if(add_slots_to_child){
+ if (add_slots_to_child) {
frappe.show_alert({
message:__('Time slot skiped, the slot {0} to {1} overlap exisiting slot {2} to {3}',
[cur_time.format('HH:mm:ss'), to_time.format('HH:mm:ss'), slot.from_time, slot.to_time]),
@@ -63,7 +64,7 @@
});
}
// add a new timeslot
- if(add_to_child && add_slots_to_child){
+ if (add_to_child && add_slots_to_child) {
frm.add_child('time_slots', {
from_time: cur_time.format('HH:mm:ss'),
to_time: to_time.format('HH:mm:ss'),
@@ -76,10 +77,11 @@
}
return overlap;
}
- function add_slots(week_day){
+
+ function add_slots(week_day) {
let cur_time = moment(values.from_time, 'HH:mm:ss');
let end_time = moment(values.to_time, 'HH:mm:ss');
- if(check_overlap_or_add_slot(week_day, cur_time, end_time, false)){
+ if (check_overlap_or_add_slot(week_day, cur_time, end_time, false)) {
frappe.confirm(__('Schedules for {0} overlaps, do you want to proceed after skiping overlaped slots ?', [week_day]),
function() {
// if Yes
@@ -88,21 +90,22 @@
function() {
// if No
frappe.show_alert({
- message:__('Slots for {0} are not added to the schedule', [week_day]),
- indicator:'red'
+ message: __('Slots for {0} are not added to the schedule', [week_day]),
+ indicator: 'red'
});
}
);
- }
- else{
+ } else {
check_overlap_or_add_slot(week_day, cur_time, end_time, true);
}
}
+
frm.refresh_field('time_slots');
- if(slot_added){
+
+ if (slot_added) {
frappe.show_alert({
- message:__('Time slots added'),
- indicator:'green'
+ message: __('Time slots added'),
+ indicator: 'green'
});
}
}
diff --git a/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.json b/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.json
index 08a1b86..cff100c 100644
--- a/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.json
+++ b/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.json
@@ -1,160 +1,71 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 1,
- "allow_rename": 1,
- "autoname": "field:schedule_name",
- "beta": 1,
- "creation": "2017-05-03 17:28:03.926787",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "actions": [],
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "field:schedule_name",
+ "beta": 1,
+ "creation": "2017-05-03 17:28:03.926787",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "disabled",
+ "schedule_details_section",
+ "schedule_name",
+ "time_slots"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "schedule_name",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Schedule Name",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "schedule_name",
+ "fieldtype": "Data",
+ "ignore_xss_filter": 1,
+ "in_list_view": 1,
+ "label": "Schedule Name",
+ "reqd": 1,
+ "unique": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "time_slots",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Time Slots",
- "length": 0,
- "no_copy": 0,
- "options": "Healthcare Schedule Time Slot",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "time_slots",
+ "fieldtype": "Table",
+ "label": "Time Slots",
+ "options": "Healthcare Schedule Time Slot"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "disabled",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Disabled",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "default": "0",
+ "fieldname": "disabled",
+ "fieldtype": "Check",
+ "label": "Disabled",
+ "print_hide": 1
+ },
+ {
+ "fieldname": "schedule_details_section",
+ "fieldtype": "Section Break",
+ "label": "Schedule Details"
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-06-29 14:55:34.795995",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Practitioner Schedule",
- "name_case": "",
- "owner": "rmehta@gmail.com",
+ ],
+ "links": [],
+ "modified": "2020-01-31 12:21:45.975488",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Practitioner Schedule",
+ "owner": "rmehta@gmail.com",
"permissions": [
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Healthcare Administrator",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Healthcare Administrator",
+ "share": 1,
"write": 1
}
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "show_name_in_global_search": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1,
- "track_seen": 0
+ ],
+ "restrict_to_domain": "Healthcare",
+ "show_name_in_global_search": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json b/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json
index 236c2b8..e4c01d7 100644
--- a/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json
+++ b/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json
@@ -1,338 +1,99 @@
{
- "allow_copy": 1,
- "allow_events_in_timeline": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 1,
- "creation": "2017-11-17 15:52:48.324157",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "actions": [],
+ "allow_copy": 1,
+ "beta": 1,
+ "creation": "2017-11-17 15:52:48.324157",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "procedure",
+ "procedure_name",
+ "department",
+ "practitioner",
+ "date",
+ "comments",
+ "appointment_booked",
+ "procedure_created",
+ "invoiced"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "procedure",
- "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": "Procedure",
- "length": 0,
- "no_copy": 0,
- "options": "Clinical Procedure Template",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "procedure",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Clinical Procedure",
+ "options": "Clinical Procedure Template",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "procedure.template",
- "fieldname": "procedure_name",
- "fieldtype": "Data",
- "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": "Procedure Name",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "procedure.template",
+ "fieldname": "procedure_name",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Procedure Name"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "department",
- "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": "Department",
- "length": 0,
- "no_copy": 0,
- "options": "Medical Department",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "procedure.medical_department",
+ "fieldname": "department",
+ "fieldtype": "Link",
+ "label": "Department",
+ "options": "Medical Department"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "practitioner",
- "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": "Referral",
- "length": 0,
- "no_copy": 0,
- "options": "Healthcare Practitioner",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "practitioner",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Referring Practitioner",
+ "options": "Healthcare Practitioner"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "date",
- "fieldtype": "Date",
- "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": "Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "date",
+ "fieldtype": "Date",
+ "in_list_view": 1,
+ "label": "Date"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "comments",
- "fieldtype": "Data",
- "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": "Comments",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "comments",
+ "fieldtype": "Data",
+ "label": "Comments"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "appointment_booked",
- "fieldtype": "Check",
- "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": "Appointment Booked",
- "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": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "appointment_booked",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "label": "Appointment Booked",
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "procedure_created",
- "fieldtype": "Check",
- "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": "Procedure Created",
- "length": 0,
- "no_copy": 1,
- "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": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "procedure_created",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "label": "Procedure Created",
+ "no_copy": 1,
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "invoiced",
- "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": "Invoiced",
- "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": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "default": "0",
+ "fieldname": "invoiced",
+ "fieldtype": "Check",
+ "label": "Invoiced",
+ "read_only": 1,
+ "search_index": 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": "2018-11-04 03:33:35.939816",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Procedure Prescription",
- "name_case": "",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1,
- "track_seen": 0,
- "track_views": 0
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-02-26 15:42:33.988081",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Procedure Prescription",
+ "owner": "Administrator",
+ "permissions": [],
+ "restrict_to_domain": "Healthcare",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/sample_collection/sample_collection.js b/erpnext/healthcare/doctype/sample_collection/sample_collection.js
index 9934ce4..2f5278b 100644
--- a/erpnext/healthcare/doctype/sample_collection/sample_collection.js
+++ b/erpnext/healthcare/doctype/sample_collection/sample_collection.js
@@ -3,7 +3,7 @@
frappe.ui.form.on('Sample Collection', {
refresh: function(frm) {
- if(frappe.defaults.get_default("require_sample_collection")){
+ if(frappe.defaults.get_default("create_sample_collection_for_lab_test")){
frm.add_custom_button(__("View Lab Tests"), function() {
frappe.route_options = {"sample": frm.doc.name};
frappe.set_route("List", "Lab Test");
diff --git a/erpnext/healthcare/doctype/sample_collection/sample_collection.json b/erpnext/healthcare/doctype/sample_collection/sample_collection.json
index 783fc3d..39cead8 100644
--- a/erpnext/healthcare/doctype/sample_collection/sample_collection.json
+++ b/erpnext/healthcare/doctype/sample_collection/sample_collection.json
@@ -1,687 +1,199 @@
{
- "allow_copy": 1,
- "allow_guest_to_view": 0,
- "allow_import": 1,
- "allow_rename": 0,
- "autoname": "naming_series:",
- "beta": 1,
- "creation": "2016-04-05 15:58:18.076977",
- "custom": 0,
- "default_print_format": "",
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Document",
- "editable_grid": 0,
+ "actions": [],
+ "allow_copy": 1,
+ "allow_import": 1,
+ "autoname": "naming_series:",
+ "beta": 1,
+ "creation": "2016-04-05 15:58:18.076977",
+ "doctype": "DocType",
+ "document_type": "Document",
+ "engine": "InnoDB",
+ "field_order": [
+ "inpatient_record",
+ "naming_series",
+ "invoiced",
+ "patient",
+ "column_break_4",
+ "patient_age",
+ "patient_sex",
+ "company",
+ "section_break_6",
+ "sample",
+ "sample_uom",
+ "sample_qty",
+ "column_break_10",
+ "collected_by",
+ "collected_time",
+ "num_print",
+ "amended_from",
+ "section_break_15",
+ "sample_details"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "patient.inpatient_record",
- "fieldname": "inpatient_record",
- "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": "Inpatient Record",
- "length": 0,
- "no_copy": 0,
- "options": "Inpatient Record",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "patient.inpatient_record",
+ "fieldname": "inpatient_record",
+ "fieldtype": "Link",
+ "label": "Inpatient Record",
+ "options": "Inpatient Record",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 1,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "fieldname": "naming_series",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Series",
- "length": 0,
- "no_copy": 1,
- "options": "HLC-SC-.YYYY.-",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "bold": 1,
+ "fieldname": "naming_series",
+ "fieldtype": "Select",
+ "label": "Series",
+ "no_copy": 1,
+ "options": "HLC-SC-.YYYY.-",
+ "print_hide": 1,
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "invoiced",
- "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": "Invoiced",
- "length": 0,
- "no_copy": 1,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "invoiced",
+ "fieldtype": "Check",
+ "label": "Invoiced",
+ "no_copy": 1,
+ "read_only": 1,
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "inpatient_record.patient",
- "fieldname": "patient",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 1,
- "label": "Patient",
- "length": 0,
- "no_copy": 0,
- "options": "Patient",
- "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": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "inpatient_record.patient",
+ "fieldname": "patient",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "in_standard_filter": 1,
+ "label": "Patient",
+ "options": "Patient",
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 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,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_4",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "patient_age",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Age",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "patient_age",
+ "fieldtype": "Data",
+ "label": "Age"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "patient.sex",
- "fieldname": "patient_sex",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Gender",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "patient.sex",
+ "fieldname": "patient_sex",
+ "fieldtype": "Data",
+ "label": "Gender"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "company",
- "fieldtype": "Link",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Company",
- "length": 0,
- "no_copy": 0,
- "options": "Company",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "label": "Company",
+ "options": "Company",
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 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,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "section_break_6",
+ "fieldtype": "Section Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sample",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Sample",
- "length": 0,
- "no_copy": 0,
- "options": "Lab Test Sample",
- "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": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "sample",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Sample",
+ "options": "Lab Test Sample",
+ "reqd": 1,
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "sample.sample_uom",
- "fieldname": "sample_uom",
- "fieldtype": "Data",
- "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": "UOM",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "sample.sample_uom",
+ "fieldname": "sample_uom",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "UOM"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "sample_quantity",
- "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": "Quantity",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_10",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_10",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "collected_by",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "label": "Collected By",
+ "options": "User"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "collected_by",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Collected By",
- "length": 0,
- "no_copy": 0,
- "options": "User",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "collected_time",
+ "fieldtype": "Datetime",
+ "label": "Collected Time"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "collected_time",
- "fieldtype": "Datetime",
- "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": "Collected Time",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "allow_on_submit": 1,
+ "default": "1",
+ "fieldname": "num_print",
+ "fieldtype": "Int",
+ "label": "No. of print",
+ "print_hide": 1,
+ "report_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 1,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "1",
- "fieldname": "num_print",
- "fieldtype": "Int",
- "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": "No. of print",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "label": "Amended From",
+ "no_copy": 1,
+ "options": "Sample Collection",
+ "print_hide": 1,
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 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": "Sample Collection",
- "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,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "section_break_15",
+ "fieldtype": "Section Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "section_break_15",
- "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,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "sample_qty",
+ "fieldtype": "Float",
+ "in_list_view": 1,
+ "label": "Quantity"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sample_collection_details",
- "fieldtype": "Long Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Collection Details",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "fieldname": "sample_details",
+ "fieldtype": "Long Text",
+ "ignore_xss_filter": 1,
+ "label": "Collection Details"
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 1,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-08-21 14:44:39.128989",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Sample Collection",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "is_submittable": 1,
+ "links": [],
+ "modified": "2020-03-25 16:55:52.376834",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Sample Collection",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 1,
- "cancel": 1,
- "create": 1,
- "delete": 0,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Laboratory User",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 1,
+ "amend": 1,
+ "cancel": 1,
+ "create": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Laboratory User",
+ "share": 1,
+ "submit": 1,
"write": 1
}
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "search_fields": "patient, sample",
- "show_name_in_global_search": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "patient",
- "track_changes": 1,
- "track_seen": 1,
- "track_views": 0
-}
+ ],
+ "restrict_to_domain": "Healthcare",
+ "search_fields": "patient, sample",
+ "show_name_in_global_search": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "patient",
+ "track_changes": 1,
+ "track_seen": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/vital_signs/vital_signs.js b/erpnext/healthcare/doctype/vital_signs/vital_signs.js
index a5f9d61..78509e0 100644
--- a/erpnext/healthcare/doctype/vital_signs/vital_signs.js
+++ b/erpnext/healthcare/doctype/vital_signs/vital_signs.js
@@ -1,49 +1,52 @@
// Copyright (c) 2016, ESS LLP and contributors
// For license information, please see license.txt
-frappe.ui.form.on("Vital Signs", "height", function(frm) {
- if(frm.doc.height && frm.doc.weight){
- calculate_bmi(frm);
+frappe.ui.form.on('Vital Signs', {
+ height: function(frm) {
+ if (frm.doc.height && frm.doc.weight) {
+ calculate_bmi(frm);
+ }
+ },
+
+ weight: function(frm) {
+ if (frm.doc.height && frm.doc.weight) {
+ calculate_bmi(frm);
+ }
+ },
+
+ bp_systolic: function(frm) {
+ if (frm.doc.bp_systolic && frm.doc.bp_diastolic) {
+ set_bp(frm);
+ }
+ },
+
+ bp_diastolic: function(frm) {
+ if (frm.doc.bp_systolic && frm.doc.bp_diastolic) {
+ set_bp(frm);
+ }
}
});
-frappe.ui.form.on("Vital Signs", "weight", function(frm) {
- if(frm.doc.height && frm.doc.weight){
- calculate_bmi(frm);
- }
-});
-
-var calculate_bmi = function(frm){
+let calculate_bmi = function(frm){
// Reference https://en.wikipedia.org/wiki/Body_mass_index
// bmi = weight (in Kg) / height * height (in Meter)
- var bmi = (frm.doc.weight/(frm.doc.height*frm.doc.height)).toFixed(2);
- var bmi_note = null;
- if(bmi<18.5){
- bmi_note = "Underweight";
- }else if(bmi>=18.5 && bmi<25){
- bmi_note = "Normal";
- }else if(bmi>=25 && bmi<30){
- bmi_note = "Overweight";
- }else if(bmi>=30){
- bmi_note = "Obese";
+ let bmi = (frm.doc.weight / (frm.doc.height * frm.doc.height)).toFixed(2);
+ let bmi_note = null;
+
+ if (bmi<18.5) {
+ bmi_note = 'Underweight';
+ } else if (bmi>=18.5 && bmi<25) {
+ bmi_note = 'Normal';
+ } else if (bmi>=25 && bmi<30) {
+ bmi_note = 'Overweight';
+ } else if (bmi>=30) {
+ bmi_note = 'Obese';
}
- frappe.model.set_value(frm.doctype,frm.docname, "bmi", bmi);
- frappe.model.set_value(frm.doctype,frm.docname, "nutrition_note", bmi_note);
+ frappe.model.set_value(frm.doctype,frm.docname, 'bmi', bmi);
+ frappe.model.set_value(frm.doctype,frm.docname, 'nutrition_note', bmi_note);
};
-frappe.ui.form.on("Vital Signs", "bp_systolic", function(frm) {
- if(frm.doc.bp_systolic && frm.doc.bp_diastolic){
- set_bp(frm);
- }
-});
-
-frappe.ui.form.on("Vital Signs", "bp_diastolic", function(frm) {
- if(frm.doc.bp_systolic && frm.doc.bp_diastolic){
- set_bp(frm);
- }
-});
-
-var set_bp = function(frm){
- var bp = frm.doc.bp_systolic+"/"+frm.doc.bp_diastolic+" mmHg";
- frappe.model.set_value(frm.doctype,frm.docname, "bp", bp);
+let set_bp = function(frm){
+ let bp = frm.doc.bp_systolic+ '/' + frm.doc.bp_diastolic + ' mmHg';
+ frappe.model.set_value(frm.doctype,frm.docname, 'bp', bp);
};
diff --git a/erpnext/healthcare/doctype/vital_signs/vital_signs.json b/erpnext/healthcare/doctype/vital_signs/vital_signs.json
index 1503f83..75726db 100644
--- a/erpnext/healthcare/doctype/vital_signs/vital_signs.json
+++ b/erpnext/healthcare/doctype/vital_signs/vital_signs.json
@@ -1,991 +1,273 @@
{
+ "actions": [],
"allow_copy": 1,
- "allow_events_in_timeline": 0,
- "allow_guest_to_view": 0,
"allow_import": 1,
- "allow_rename": 0,
"beta": 1,
"creation": "2017-02-02 11:00:24.853005",
- "custom": 0,
- "docstatus": 0,
"doctype": "DocType",
- "document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
+ "field_order": [
+ "inpatient_record",
+ "patient",
+ "patient_name",
+ "appointment",
+ "encounter",
+ "column_break_2",
+ "signs_date",
+ "signs_time",
+ "sb_vs",
+ "temperature",
+ "pulse",
+ "respiratory_rate",
+ "tongue",
+ "abdomen",
+ "column_break_8",
+ "reflexes",
+ "bp_systolic",
+ "bp_diastolic",
+ "bp",
+ "vital_signs_note",
+ "sb_nutrition_values",
+ "height",
+ "weight",
+ "bmi",
+ "column_break_14",
+ "nutrition_note",
+ "company",
+ "amended_from"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fetch_from": "patient.inpatient_record",
"fieldname": "inpatient_record",
"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": "Inpatient Record",
- "length": 0,
- "no_copy": 0,
"options": "Inpatient Record",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "read_only": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fetch_from": "inpatient_record.patient",
"fieldname": "patient",
"fieldtype": "Link",
- "hidden": 0,
"ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Patient",
- "length": 0,
- "no_copy": 0,
"options": "Patient",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "reqd": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fetch_from": "patient.patient_name",
"fieldname": "patient_name",
"fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Patient Name",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "read_only": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "appointment",
"fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
"in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Appointment",
- "length": 0,
- "no_copy": 1,
"options": "Patient Appointment",
- "permlevel": 0,
- "precision": "",
"print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "read_only": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "encounter",
"fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
"in_filter": 1,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Patient Encounter",
- "length": 0,
"no_copy": 1,
"options": "Patient Encounter",
- "permlevel": 0,
- "precision": "",
"print_hide": 1,
- "print_hide_if_no_value": 0,
"read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "report_hide": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "column_break_2",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "fieldtype": "Column Break"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"default": "Today",
"fieldname": "signs_date",
"fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "reqd": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
"fieldname": "signs_time",
"fieldtype": "Time",
- "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": "Time",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "reqd": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "sb_vs",
"fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Vital Signs",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Vital Signs"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"description": "Presence of a fever (temp > 38.5 \u00b0C/101.3 \u00b0F or sustained temp > 38 \u00b0C/100.4 \u00b0F)",
"fieldname": "temperature",
"fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
"ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
"in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Body Temperature",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Body Temperature"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"description": "Adults' pulse rate is anywhere between 50 and 80 beats per minute.",
"fieldname": "pulse",
"fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
"ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
"in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Heart Rate / Pulse",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Heart Rate / Pulse"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"description": "Normal reference range for an adult is 16\u201320 breaths/minute (RCP 2012)",
"fieldname": "respiratory_rate",
"fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
"ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
"in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Respiratory rate",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Respiratory rate"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "tongue",
"fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Tongue",
- "length": 0,
- "no_copy": 0,
- "options": "\nCoated\nVery Coated\nNormal\nFurry\nCuts",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "options": "\nCoated\nVery Coated\nNormal\nFurry\nCuts"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "abdomen",
"fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Abdomen",
- "length": 0,
- "no_copy": 0,
- "options": "\nNormal\nBloated\nFull\nFluid\nConstipated",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "options": "\nNormal\nBloated\nFull\nFluid\nConstipated"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "column_break_8",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "fieldtype": "Column Break"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "reflexes",
"fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Reflexes",
- "length": 0,
- "no_copy": 0,
- "options": "\nNormal\nHyper\nVery Hyper\nOne Sided",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "options": "\nNormal\nHyper\nVery Hyper\nOne Sided"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "bp_systolic",
"fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
"ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
"in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Blood Pressure (systolic)",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Blood Pressure (systolic)"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "",
"fieldname": "bp_diastolic",
"fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
"ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
"in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Blood Pressure (diastolic)",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Blood Pressure (diastolic)"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"description": "Normal resting blood pressure in an adult is approximately 120 mmHg systolic, and 80 mmHg diastolic, abbreviated \"120/80 mmHg\"",
"fieldname": "bp",
"fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Blood Pressure",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "read_only": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "vital_signs_note",
"fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
"ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Notes",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Notes"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "sb_nutrition_values",
"fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Nutrition Values",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Nutrition Values"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "height",
"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": "Height (In Meter)",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Height (In Meter)"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "weight",
"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": "Weight (In Kilogram)",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Weight (In Kilogram)"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"default": "0.00",
"fieldname": "bmi",
"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": "BMI",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "read_only": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "column_break_14",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "fieldtype": "Column Break"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "nutrition_note",
"fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
"ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Notes",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Notes"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Company",
- "length": 0,
- "no_copy": 0,
- "options": "Company",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "options": "Company"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 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": "Vital Signs",
- "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,
- "translatable": 0,
- "unique": 0
+ "read_only": 1
}
],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
"is_submittable": 1,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-11-23 14:14:05.933292",
+ "links": [],
+ "modified": "2020-03-04 17:19:29.549889",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Vital Signs",
- "name_case": "",
"owner": "Administrator",
"permissions": [
{
- "amend": 0,
"cancel": 1,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Physician",
- "set_user_permissions": 0,
"share": 1,
"submit": 1,
"write": 1
},
{
- "amend": 0,
"cancel": 1,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Nursing User",
- "set_user_permissions": 0,
"share": 1,
"submit": 1,
"write": 1
}
],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
"restrict_to_domain": "Healthcare",
"search_fields": "patient, signs_date",
"show_name_in_global_search": 1,
@@ -993,6 +275,5 @@
"sort_order": "DESC",
"title_field": "patient",
"track_changes": 1,
- "track_seen": 1,
- "track_views": 0
+ "track_seen": 1
}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/vital_signs/vital_signs.py b/erpnext/healthcare/doctype/vital_signs/vital_signs.py
index bf4dace..959e850 100644
--- a/erpnext/healthcare/doctype/vital_signs/vital_signs.py
+++ b/erpnext/healthcare/doctype/vital_signs/vital_signs.py
@@ -6,6 +6,7 @@
import frappe
from frappe.model.document import Document
from frappe.utils import cstr
+from frappe import _
class VitalSigns(Document):
def on_submit(self):
@@ -16,34 +17,35 @@
def insert_vital_signs_to_medical_record(doc):
subject = set_subject_field(doc)
- medical_record = frappe.new_doc("Patient Medical Record")
+ medical_record = frappe.new_doc('Patient Medical Record')
medical_record.patient = doc.patient
medical_record.subject = subject
- medical_record.status = "Open"
+ medical_record.status = 'Open'
medical_record.communication_date = doc.signs_date
- medical_record.reference_doctype = "Vital Signs"
+ medical_record.reference_doctype = 'Vital Signs'
medical_record.reference_name = doc.name
medical_record.reference_owner = doc.owner
+ medical_record.flags.ignore_mandatory = True
medical_record.save(ignore_permissions=True)
def delete_vital_signs_from_medical_record(doc):
- medical_record_id = frappe.db.sql("select name from `tabPatient Medical Record` where reference_name=%s",(doc.name))
- if medical_record_id and medical_record_id[0][0]:
- frappe.delete_doc("Patient Medical Record", medical_record_id[0][0])
+ medical_record = frappe.db.get_value('Patient Medical Record', {'reference_name': doc.name})
+ if medical_record:
+ frappe.delete_doc('Patient Medical Record', medical_record)
def set_subject_field(doc):
- subject = ""
+ subject = ''
if(doc.temperature):
- subject += "Temperature: \n"+ cstr(doc.temperature)+". "
+ subject += _('Temperature: ') + '\n'+ cstr(doc.temperature) + '. '
if(doc.pulse):
- subject += "Pulse: \n"+ cstr(doc.pulse)+". "
+ subject += _('Pulse: ') + '\n' + cstr(doc.pulse) + '. '
if(doc.respiratory_rate):
- subject += "Respiratory Rate: \n"+ cstr(doc.respiratory_rate)+". "
+ subject += _('Respiratory Rate: ') + '\n' + cstr(doc.respiratory_rate) + '. '
if(doc.bp):
- subject += "BP: \n"+ cstr(doc.bp)+". "
+ subject += _('BP: ') + '\n' + cstr(doc.bp) + '. '
if(doc.bmi):
- subject += "BMI: \n"+ cstr(doc.bmi)+". "
+ subject += _('BMI: ') + '\n' + cstr(doc.bmi) + '. '
if(doc.nutrition_note):
- subject += "Note: \n"+ cstr(doc.nutrition_note)+". "
+ subject += _('Note: ') + '\n' + cstr(doc.nutrition_note) + '. '
return subject
diff --git a/erpnext/healthcare/page/appointment_analytic/appointment_analytic.js b/erpnext/healthcare/page/appointment_analytic/appointment_analytic.js
deleted file mode 100644
index 9f2e552..0000000
--- a/erpnext/healthcare/page/appointment_analytic/appointment_analytic.js
+++ /dev/null
@@ -1,205 +0,0 @@
-frappe.pages['appointment-analytic'].on_page_load = function(wrapper) {
- frappe.ui.make_app_page({
- parent: wrapper,
- title: 'Appointment Analytics',
- single_column: true
- });
- new erpnext.AppointmentAnalytics(wrapper);
- frappe.breadcrumbs.add("Medical");
-};
-
-erpnext.AppointmentAnalytics = frappe.views.TreeGridReport.extend({
- init: function(wrapper) {
- this._super({
- title: __("Appointment Analytics"),
- parent: $(wrapper).find('.layout-main'),
- page: wrapper.page,
- doctypes: ["Patient Appointment", "Healthcare Practitioner", "Medical Department", "Appointment Type", "Patient"],
- tree_grid: { show: true }
- });
-
- this.tree_grids = {
- "Medical Department": {
- label: __("Department"),
- show: true,
- item_key: "practitioner",
- parent_field: "department",
- formatter: function(item) {
- return item.name;
- }
- },
- "Healthcare Practitioner": {
- label: __("Healthcare Practitioner"),
- show: true,
- item_key: "practitioner",
- formatter: function(item) {
- return item.name;
- }
- },
- };
- },
- setup_columns: function() {
- this.tree_grid = this.tree_grids[this.tree_type];
-
- var std_columns = [
- {id: "name", name: this.tree_grid.label, field: "name", width: 300},
- {id: "total", name: "Total", field: "total", plot: false,
- formatter: this.currency_formatter}
- ];
-
- this.make_date_range_columns();
- this.columns = std_columns.concat(this.columns);
- },
- filters: [
- {fieldtype:"Select", label: __("Tree Type"), fieldname: "tree_type",
- options:["Healthcare Practitioner", "Medical Department"], filter: function(val, item, opts, me) {
- return me.apply_zero_filter(val, item, opts, me);}},
- {fieldtype:"Select", label: __("Status"), fieldname: "status",
- options:[
- {label: __("Select Status"), value: "Select Status..."},
- {label: __("Open"), value: "Open"},
- {label: __("Closed"), value: "Closed"},
- {label: __("Pending"), value: "Pending"},
- {label: __("Scheduled"), value: "Scheduled"},
- {label: __("Cancelled"), value: "Cancelled"}]},
- {fieldtype:"Select", label: __("Type"), link:"Appointment Type", fieldname: "type",
- default_value: __("Select Type...")},
- {fieldtype:"Select", label: __("Healthcare Practitioner"), link:"Healthcare Practitioner", fieldname: "practitioner",
- default_value: __("Select Healthcare Practitioner..."), filter: function(val, item, opts) {
- return val == opts.default_value || item.name == val || item._show;
- }, link_formatter: {filter_input: "practitioner"}},
- {fieldtype:"Select", label: __("Department"), link:"Medical Department", fieldname: "department",
- default_value: __("Select Department..."), filter: function(val, item, opts) {
- return val == opts.default_value || item.department == val || item._show;
- }, link_formatter: {filter_input: "department"}},
- {fieldtype:"Date", label: __("From Date"), fieldname: "from_date"},
- {fieldtype:"Date", label: __("To Date"), fieldname: "to_date"},
- {fieldtype:"Select", label: __("Range"), fieldname: "range",
- options:[{label: __("Daily"), value: "Daily"}, {label: __("Weekly"), value: "Weekly"},
- {label: __("Monthly"), value: "Monthly"}, {label: __("Quarterly"), value: "Quarterly"},
- {label: __("Yearly"), value: "Yearly"}]}
- ],
- setup_filters: function() {
- this._super();
- this.trigger_refresh_on_change(["tree_type", "practitioner", "department", "status", "type"]);
-
- // this.show_zero_check()
- },
- init_filter_values: function() {
- this._super();
- this.filter_inputs.range.val('Quarterly');
- },
- prepare_data: function() {
- var me = this;
- if (!this.tl) {
- this.tl = frappe.report_dump.data["Patient Appointment"];
- }
- if(!this.data || me.item_type != me.tree_type) {
- var items = null;
- if(me.tree_type=='Healthcare Practitioner') {
- items = frappe.report_dump.data["Healthcare Practitioner"];
- } if(me.tree_type=='Medical Department') {
- items = this.prepare_tree("Healthcare Practitioner", "Medical Department");
- }
- me.item_type = me.tree_type;
- me.parent_map = {};
- me.item_by_name = {};
- me.data = [];
-
- $.each(items, function(i, v) {
- var d = copy_dict(v);
-
- me.data.push(d);
- me.item_by_name[d.name] = d;
- if(d[me.tree_grid.parent_field]) {
- me.parent_map[d.name] = d[me.tree_grid.parent_field];
- }
- me.reset_item_values(d);
- });
-
- this.set_indent();
-
-
- } else {
- // otherwise, only reset values
- $.each(this.data, function(i, d) {
- me.reset_item_values(d);
- });
- }
- this.prepare_balances();
- if(me.tree_grid.show) {
- this.set_totals(false);
- this.update_groups();
- } else {
- this.set_totals(true);
- }
-
-
- },
- prepare_balances: function() {
- var me = this;
- var from_date = frappe.datetime.str_to_obj(this.from_date);
- var status = this.status;
- var type = this.type;
- var to_date = frappe.datetime.str_to_obj(this.to_date);
- $.each(this.tl, function(i, tl) {
- if (me.is_default('company') ? true : tl.company === me.company) {
-
- var date = frappe.datetime.str_to_obj(tl.appointment_date);
- if (date >= from_date && date <= to_date) {
- var item = me.item_by_name[tl[me.tree_grid.item_key]] ||
- me.item_by_name['Not Set'];
-
- var d = tl.appointment_date.split(" ")[0];
- if(status == "Select Status..." && type=="Select Type...")
- {
- item[me.column_map[d].field] += 1;
-
- }else if (status !== "Select Status..." && type == "Select Type..."){
- if(status === tl.status){item[me.column_map[d].field] += 1;}
- }else if (status == "Select Status..." && type !== "Select Type..."){
- if(type === tl.appointment_type){item[me.column_map[d].field] += 1;}
- }else {
- if(type === tl.appointment_type && status === tl.status){item[me.column_map[d].field] += 1;}
- }
- }
- }
- });
- },
- update_groups: function() {
- var me = this;
-
- $.each(this.data, function(i, item) {
- var parent = me.parent_map[item.name];
- while(parent) {
- var parent_group = me.item_by_name[parent];
-
- $.each(me.columns, function(c, col) {
- if (col.formatter == me.currency_formatter) {
- parent_group[col.field] =
- flt(parent_group[col.field])
- + flt(item[col.field]);
- }
- });
- parent = me.parent_map[parent];
- }
- });
- },
- set_totals: function(sort) {
- var me = this;
- $.each(this.data, function(i, d) {
- d.total = 0.0;
- $.each(me.columns, function(i, col) {
- if(col.formatter==me.currency_formatter && !col.hidden && col.field!="total")
- d.total += d[col.field];
- });
- });
-
- if(sort)this.data = this.data.sort(function(a, b) { return b.total - a.total; });
-
- if(!this.checked) {
- this.data[0].checked = true;
- }
- }
-
-});
diff --git a/erpnext/healthcare/page/appointment_analytic/appointment_analytic.json b/erpnext/healthcare/page/appointment_analytic/appointment_analytic.json
deleted file mode 100644
index ac5ca1a..0000000
--- a/erpnext/healthcare/page/appointment_analytic/appointment_analytic.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "content": null,
- "creation": "2016-08-18 12:29:52.497819",
- "docstatus": 0,
- "doctype": "Page",
- "idx": 0,
- "modified": "2018-08-06 11:40:53.082863",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "appointment-analytic",
- "owner": "Administrator",
- "page_name": "Appointment Analytics",
- "restrict_to_domain": "Healthcare",
- "roles": [
- {
- "role": "Physician"
- }
- ],
- "script": null,
- "standard": "Yes",
- "style": null,
- "system_page": 0,
- "title": "Appointment Analytics"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/print_format/encounter_print/encounter_print.json b/erpnext/healthcare/print_format/encounter_print/encounter_print.json
index 20e44b7..ec1e0f2 100644
--- a/erpnext/healthcare/print_format/encounter_print/encounter_print.json
+++ b/erpnext/healthcare/print_format/encounter_print/encounter_print.json
@@ -1,22 +1,22 @@
{
- "align_labels_right": 0,
- "creation": "2017-04-10 14:05:53.355863",
- "custom_format": 1,
- "disabled": 0,
- "doc_type": "Patient Encounter",
- "docstatus": 0,
- "doctype": "Print Format",
- "font": "Default",
- "html": "<div >\n {% if letter_head and not no_letterhead -%}\n <div class=\"letter-head\">{{ letter_head }}</div>\n <hr>\n {% else %}\n <div align=\"right\">\n <h1>{{doc.name}}</h1>\n </div>\n {%- endif %}\n <div class=\"row section-break\">\n <div class=\"col-xs-6 column-break\">\n {% if doc.appointment %}\n\t <div class=\"row\">\n\t\t\t<div class=\"col-xs-4 text-left\">\n\t\t\t<label>Appointment</label>\n\t\t\t</div>\n\t\t\t<div class=\"col-xs-7 value\">\n\t\t\t<strong>: </strong>{{doc.appointment}}\n\t\t\t</div>\n\t\t</div>\n\t\t{%- endif -%}\n\n <div class=\"row\">\n\t\t <div class=\"col-xs-4 text-left\">\n\t\t\t <label>Patient</label>\n\t\t </div>\n {% if doc.patient %}\n\t\t <div class=\"col-xs-7 value\">\n\t\t\t <strong>: </strong>{{doc.patient}}\n\t\t </div>\n {% else %}\n <div class=\"col-xs-7 value\">\n\t\t\t <strong>: </strong><em>Patient Name</em>\n\t\t </div>\n {%- endif -%}\n\t\t</div>\n\t <div class=\"row\">\n\t\t\t<div class=\"col-xs-4 text-left\">\n\t\t\t\t<label>Age</label>\n\t\t\t</div>\n\t\t\t<div class=\"col-xs-7 value\">\n\t\t\t <strong>: </strong> {{doc.patient_age}}\n\t\t\t</div>\n\t\t</div>\n\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n\t\t\t\t<label>Gender</label>\n\t\t\t</div>\n\t\t\t<div class=\"col-xs-7 value\">\n\t\t\t <strong>: </strong> {{doc.patient_sex}}\n\t\t\t</div>\n </div>\n\n </div>\n <div class=\"col-xs-6 column-break\">\n\n <div class=\"row\">\n\t <div class=\"col-xs-4 text-left\">\n\t\t <label>Healthcare Practitioner</label>\n\t </div>\n {% if doc.practitioner %}\n\t <div class=\"col-xs-7 text-left value\">\n\t\t\t<strong>: </strong>{{doc.practitioner}}\n\t </div>\n {%- endif -%}\n\t</div>\n\n {% if doc.encounter_date %}\n\t <div class=\"row\">\n\t\t<div class=\"col-xs-4 text-left\">\n\t\t<label>Date</label>\n\t\t</div>\n\t\t<div class=\"col-xs-7 text-left value\">\n\t\t<strong>: </strong>{{doc.encounter_date}}\n\t\t</div>\n </div>\n\t {%- endif -%}\n {% if doc.encounter_time %}\n\t <div class=\"row\">\n\t\t<div class=\"col-xs-4 text-left\">\n\t\t<label>Time</label>\n\t\t</div>\n\t\t<div class=\"col-xs-7 text-left value\">\n\t\t<strong>: </strong>{{doc.encounter_time}}\n\t\t</div>\n </div>\n\t {%- endif -%}\n {% if doc.visit_department %}\n\t <div class=\"row\">\n\t\t<div class=\"col-xs-4 text-left\">\n\t\t<label>Department</label>\n\t\t</div>\n\t\t<div class=\"col-xs-7 text-left value\">\n\t\t<strong>: </strong>{{doc.visit_department}}\n\t\t</div>\n </div>\n {%- endif -%}\n </div>\n\n </div>\n\n</div>\n<div>\n <hr>\n {% if doc.symptoms_in_print%}\n {% if doc.symptoms %}\n Complaints:\n <strong>{{doc.symptoms}}</strong>\n \t <br>\n {%- endif -%}\n {%- endif -%}\n\n {% if doc.diagnosis_in_print%}\n {% if doc.diagnosis %}\n \t Diagnosis:\n <strong>{{doc.diagnosis}}</strong>\n <br>\n {%- endif -%}\n {%- endif -%}\n\n</div>\n\n<div>\n {% if doc.drug_prescription %}\n <br>\n Rx,\n <table class=\"table\">\n <tbody>\n <!--<tr>\n <th>Drug</th>\n <th class=\"text-left\">Dosage</th>\n <th class=\"text-left\">Period</th>\n <th>Remark</th>\n </tr>-->\n\n {%- for row in doc.drug_prescription -%}\n <tr>\n <td style=\"width: 30%;border:none;\">\n {%- if row.drug_name -%}<b>{{ row.drug_name }}</b>{%- endif -%}\n </td>\n \t<td style=\"width: 20%;text-align: left;border:none;\">\n {%- if row.dosage -%}{{ row.dosage }}{%- endif -%}\n </td>\n \t<td style=\"width: 20%;text-align: left;border:none;\">\n {%- if row.period -%}{{ row.period }}{%- endif -%}\n\t\t </td>\n <td style=\"width: 30%;text-align: left;border:none;\">\n\t\t\t <div style=\"border: 0px;\">\n {%- if row.comment -%}{{ row.comment }}{%- endif -%}\n </div>\n\t\t </td>\n </tr>\n\t {%- endfor -%}\n </tbody>\n </table>\n\n\n {%- endif -%}\n</div>\n\n\n<div>\n {% if doc.lab_test_prescription %}\n Investigations,\n <table class=\"table\">\n <tbody>\n <!--<tr>\n <th>Test</th>\n <th>Remark</th>\n </tr>-->\n\n {%- for row in doc.lab_test_prescription -%}\n <tr>\n <td style=\"width: 30%;border:none;\">\n {%- if row.lab_test_name -%}<b>{{ row.lab_test_name }}</b>{%- endif -%}\n </td>\n <td style=\"width: 30%;text-align: left;border:none;\">\n\t\t\t <div style=\"border: 0px;\">\n {%- if row.lab_test_comment -%}{{ row.lab_test_comment }}{%- endif -%}\n </div>\n\t\t </td>\n </tr>\n\n\t {%- endfor -%}\n </tbody>\n </table>\n\n\n {%- endif -%}\n</div>\n<div>\n {% if doc.encounter_comment %}\n <br>\n {{doc.encounter_comment}}\n {%- endif -%}\n</div>\n",
- "idx": 0,
- "line_breaks": 0,
- "modified": "2018-09-04 11:52:54.473702",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Encounter Print",
- "owner": "Administrator",
- "print_format_builder": 0,
- "print_format_type": "Server",
- "show_section_headings": 0,
+ "align_labels_right": 0,
+ "creation": "2017-04-10 14:05:53.355863",
+ "custom_format": 1,
+ "disabled": 0,
+ "doc_type": "Patient Encounter",
+ "docstatus": 0,
+ "doctype": "Print Format",
+ "font": "Default",
+ "html": "<div >\n {% if letter_head and not no_letterhead -%}\n <div class=\"letter-head\">{{ letter_head }}</div>\n <hr>\n {% else %}\n <div align=\"right\">\n <h1>{{doc.name}}</h1>\n </div>\n {%- endif %}\n <div class=\"row section-break\">\n <div class=\"col-xs-6 column-break\">\n {% if doc.appointment %}\n\t <div class=\"row\">\n\t\t\t<div class=\"col-xs-4 text-left\">\n\t\t\t<label>Appointment</label>\n\t\t\t</div>\n\t\t\t<div class=\"col-xs-7 value\">\n\t\t\t<strong>: </strong>{{doc.appointment}}\n\t\t\t</div>\n\t\t</div>\n\t\t{%- endif -%}\n\n <div class=\"row\">\n\t\t <div class=\"col-xs-4 text-left\">\n\t\t\t <label>Patient</label>\n\t\t </div>\n {% if doc.patient %}\n\t\t <div class=\"col-xs-7 value\">\n\t\t\t <strong>: </strong>{{doc.patient}}\n\t\t </div>\n {% else %}\n <div class=\"col-xs-7 value\">\n\t\t\t <strong>: </strong><em>Patient Name</em>\n\t\t </div>\n {%- endif -%}\n\t\t</div>\n\t <div class=\"row\">\n\t\t\t<div class=\"col-xs-4 text-left\">\n\t\t\t\t<label>Age</label>\n\t\t\t</div>\n\t\t\t<div class=\"col-xs-7 value\">\n\t\t\t <strong>: </strong> {{doc.patient_age}}\n\t\t\t</div>\n\t\t</div>\n\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n\t\t\t\t<label>Gender</label>\n\t\t\t</div>\n\t\t\t<div class=\"col-xs-7 value\">\n\t\t\t <strong>: </strong> {{doc.patient_sex}}\n\t\t\t</div>\n </div>\n\n </div>\n <div class=\"col-xs-6 column-break\">\n\n <div class=\"row\">\n\t <div class=\"col-xs-4 text-left\">\n\t\t <label>Healthcare Practitioner</label>\n\t </div>\n {% if doc.practitioner %}\n\t <div class=\"col-xs-7 text-left value\">\n\t\t\t<strong>: </strong>{{doc.practitioner}}\n\t </div>\n {%- endif -%}\n\t</div>\n\n {% if doc.encounter_date %}\n\t <div class=\"row\">\n\t\t<div class=\"col-xs-4 text-left\">\n\t\t<label>Date</label>\n\t\t</div>\n\t\t<div class=\"col-xs-7 text-left value\">\n\t\t<strong>: </strong>{{doc.encounter_date}}\n\t\t</div>\n </div>\n\t {%- endif -%}\n {% if doc.encounter_time %}\n\t <div class=\"row\">\n\t\t<div class=\"col-xs-4 text-left\">\n\t\t<label>Time</label>\n\t\t</div>\n\t\t<div class=\"col-xs-7 text-left value\">\n\t\t<strong>: </strong>{{doc.encounter_time}}\n\t\t</div>\n </div>\n\t {%- endif -%}\n {% if doc.medical_department %}\n\t <div class=\"row\">\n\t\t<div class=\"col-xs-4 text-left\">\n\t\t<label>Department</label>\n\t\t</div>\n\t\t<div class=\"col-xs-7 text-left value\">\n\t\t<strong>: </strong>{{doc.visit_department}}\n\t\t</div>\n </div>\n {%- endif -%}\n </div>\n\n </div>\n\n</div>\n<div>\n <hr>\n {% if doc.symptoms_in_print%}\n {% if doc.symptoms %}\n Complaints:\n <strong>{{doc.symptoms}}</strong>\n \t <br>\n {%- endif -%}\n {%- endif -%}\n\n {% if doc.diagnosis_in_print%}\n {% if doc.diagnosis %}\n \t Diagnosis:\n <strong>{{doc.diagnosis}}</strong>\n <br>\n {%- endif -%}\n {%- endif -%}\n\n</div>\n\n<div>\n {% if doc.drug_prescription %}\n <br>\n Rx,\n <table class=\"table\">\n <tbody>\n <!--<tr>\n <th>Drug</th>\n <th class=\"text-left\">Dosage</th>\n <th class=\"text-left\">Period</th>\n <th>Remark</th>\n </tr>-->\n\n {%- for row in doc.drug_prescription -%}\n <tr>\n <td style=\"width: 30%;border:none;\">\n {%- if row.drug_name -%}<b>{{ row.drug_name }}</b>{%- endif -%}\n </td>\n \t<td style=\"width: 20%;text-align: left;border:none;\">\n {%- if row.dosage -%}{{ row.dosage }}{%- endif -%}\n </td>\n \t<td style=\"width: 20%;text-align: left;border:none;\">\n {%- if row.period -%}{{ row.period }}{%- endif -%}\n\t\t </td>\n <td style=\"width: 30%;text-align: left;border:none;\">\n\t\t\t <div style=\"border: 0px;\">\n {%- if row.comment -%}{{ row.comment }}{%- endif -%}\n </div>\n\t\t </td>\n </tr>\n\t {%- endfor -%}\n </tbody>\n </table>\n\n\n {%- endif -%}\n</div>\n\n\n<div>\n {% if doc.lab_test_prescription %}\n Investigations,\n <table class=\"table\">\n <tbody>\n <!--<tr>\n <th>Test</th>\n <th>Remark</th>\n </tr>-->\n\n {%- for row in doc.lab_test_prescription -%}\n <tr>\n <td style=\"width: 30%;border:none;\">\n {%- if row.lab_test_name -%}<b>{{ row.lab_test_name }}</b>{%- endif -%}\n </td>\n <td style=\"width: 30%;text-align: left;border:none;\">\n\t\t\t <div style=\"border: 0px;\">\n {%- if row.lab_test_comment -%}{{ row.lab_test_comment }}{%- endif -%}\n </div>\n\t\t </td>\n </tr>\n\n\t {%- endfor -%}\n </tbody>\n </table>\n\n\n {%- endif -%}\n</div>\n<div>\n {% if doc.encounter_comment %}\n <br>\n {{doc.encounter_comment}}\n {%- endif -%}\n</div>\n",
+ "idx": 0,
+ "line_breaks": 0,
+ "modified": "2018-09-04 11:52:54.473702",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Encounter Print",
+ "owner": "Administrator",
+ "print_format_builder": 0,
+ "print_format_type": "Server",
+ "show_section_headings": 0,
"standard": "Yes"
}
\ No newline at end of file
diff --git a/erpnext/healthcare/print_format/lab_test_print/lab_test_print.json b/erpnext/healthcare/print_format/lab_test_print/lab_test_print.json
index 6badc6f..e8e95d8 100644
--- a/erpnext/healthcare/print_format/lab_test_print/lab_test_print.json
+++ b/erpnext/healthcare/print_format/lab_test_print/lab_test_print.json
@@ -1,22 +1,22 @@
{
- "align_labels_right": 0,
- "creation": "2017-04-24 15:38:45.332473",
- "custom_format": 1,
- "disabled": 0,
- "doc_type": "Lab Test",
- "docstatus": 0,
- "doctype": "Print Format",
- "font": "Default",
- "html": "<div >\n {% if letter_head and not no_letterhead -%}\n <div class=\"letter-head\">{{ letter_head }}</div>\n <hr>\n {%- endif %}\n\n {% if (doc.docstatus != 1) %}\n <b>Lab Tests have to be Submitted for Print .. !</b>\n {% elif (frappe.db.get_value(\"Healthcare Settings\", \"None\", \"require_test_result_approval\") == '1' and doc.approval_status != \"Approved\") %}\n <b>Lab Tests have to be Approved for Print .. !</b>\n {%- else -%}\n <div class=\"row section-break\">\n <div class=\"col-xs-6 column-break\">\n\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Patient</label>\n </div>\n {% if doc.patient %}\n <div class=\"col-xs-7 value\">\n <strong>: </strong>{{doc.patient}}\n </div>\n {% else %}\n <div class=\"col-xs-7 value\">\n <strong>: </strong><em>Patient Name</em>\n </div>\n {%- endif -%}\n </div>\n\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Age</label>\n </div>\n <div class=\"col-xs-7 value\">\n <strong>: </strong> {{doc.patient_age}}\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Gender</label>\n </div>\n <div class=\"col-xs-7 value\">\n <strong>: </strong> {{doc.patient_sex}}\n </div>\n </div>\n\n </div>\n\n <div class=\"col-xs-6 column-break\">\n\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Practitioner</label>\n </div>\n {% if doc.practitioner %}\n <div class=\"col-xs-7 text-left value\">\n <strong>: </strong>{{doc.practitioner}}\n </div>\n {%- endif -%}\n </div>\n\n {% if doc.sample_date %}\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Sample Date</label>\n </div>\n <div class=\"col-xs-7 text-left value\">\n <strong>: </strong>{{doc.sample_date}}\n </div>\n </div>\n {%- endif -%}\n\n {% if doc.result_date %}\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Result Date</label>\n </div>\n <div class=\"col-xs-7 text-left value\">\n <strong>: </strong>{{doc.result_date}}\n </div>\n </div>\n {%- endif -%}\n\n </div>\n\n </div>\n\n <div align=\"center\">\n <hr><h4 class=\"text-uppercase\"><b><u>Department of {{doc.department}}</u></b></h4>\n </div>\n\n <table class=\"table\">\n <tbody>\n {%- if doc.normal_test_items -%}\n <tr>\n <th>Name of Test</th>\n <th class=\"text-left\">Result</th>\n <th class=\"text-right\">Normal Range</th>\n </tr>\n\n {%- if doc.normal_test_items|length > 1 %}\n <tr><td style=\"width: 40%;\"> <b>{{ doc.lab_test_name }}</b> </td><td></td></tr>\n {%- endif -%}\n\n {%- for row in doc.normal_test_items -%}\n <tr>\n <td style=\"width: 40%;border:none;\">\n {%- if doc.normal_test_items|length > 1 %}  {%- endif -%}\n {%- if row.lab_test_name -%}<b>{{ row.lab_test_name }}</b>\n {%- else -%}   {%- endif -%}\n {%- if row.lab_test_event -%}   {{ row.lab_test_event }}{%- endif -%}\n </td>\n\n <td style=\"width: 20%;text-align: left;border:none;\">\n {%- if row.result_value -%}{{ row.result_value }}{%- endif -%} \n {%- if row.lab_test_uom -%}{{ row.lab_test_uom }}{%- endif -%}\n </td>\n\n <td style=\"width: 30%;text-align: right;border:none;\">\n <div style=\"border: 0px;\">\n {%- if row.normal_range -%}{{ row.normal_range }}{%- endif -%}\n </div>\n </td>\n </tr>\n\n {%- endfor -%}\n {%- endif -%}\n </tbody>\n </table>\n\n <table class=\"table\">\n <tbody>\n {%- if doc.special_test_items -%}\n <tr>\n <th>Name of Test</th>\n <th class=\"text-left\">Result</th>\n </tr>\n <tr><td style=\"width: 30%;border:none;\"> <b>{{ doc.lab_test_name }}</b> </td><td></td></tr>\n {%- for row in doc.special_test_items -%}\n <tr>\n <td style=\"width: 30%;border:none;\">   {{ row.lab_test_particulars }} </td>\n <td style=\"width: 70%;text-align: left;border:none;\">\n {%- if row.result_value -%}{{ row.result_value }}{%- endif -%}\n </td>\n </tr>\n\n {%- endfor -%}\n {%- endif -%}\n\n {%- if doc.sensitivity_test_items -%}\n <tr>\n <th>Antibiotic</th>\n <th class=\"text-left\">Sensitivity</th>\n </tr>\n {%- for row in doc.sensitivity_test_items -%}\n <tr>\n <td style=\"width: 30%;border:none;\"> {{ row.antibiotic }} </td>\n <td style=\"width: 70%;text-align: left;border:none;\">{{ row.antibiotic_sensitivity }}</td>\n </tr>\n\n {%- endfor -%}\n {%- endif -%}\n\n </tbody>\n </table>\n {%- endif -%}\n\n <div align=\"right\">\n {%- if (frappe.db.get_value(\"Healthcare Settings\", \"None\", \"employee_name_and_designation_in_print\") == '1') -%}\n <h6 class=\"text-uppercase\"><b>{{doc.employee_name}}</b></h6>\n <h6 class=\"text-uppercase\"><b>{{doc.employee_designation}}</b></h6>\n {%- else -%}\n <h6 ><b>{{frappe.db.get_value(\"Healthcare Settings\", \"None\", \"custom_signature_in_print\") }}</b></h6>\n {%- endif -%}\n </div>\n</div>\n",
- "idx": 0,
- "line_breaks": 0,
- "modified": "2018-09-04 12:03:47.066918",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Lab Test Print",
- "owner": "Administrator",
- "print_format_builder": 0,
- "print_format_type": "Server",
- "show_section_headings": 0,
+ "align_labels_right": 0,
+ "creation": "2017-04-24 15:38:45.332473",
+ "custom_format": 1,
+ "disabled": 0,
+ "doc_type": "Lab Test",
+ "docstatus": 0,
+ "doctype": "Print Format",
+ "font": "Default",
+ "html": "<div >\n {% if letter_head and not no_letterhead -%}\n <div class=\"letter-head\">{{ letter_head }}</div>\n <hr>\n {%- endif %}\n\n {% if (doc.docstatus != 1) %}\n <b>Lab Tests have to be Submitted for Print .. !</b>\n {% elif (frappe.db.get_value(\"Healthcare Settings\", \"None\", \"lab_test_approval_required\") == '1' and doc.approval_status != \"Approved\") %}\n <b>Lab Tests have to be Approved for Print .. !</b>\n {%- else -%}\n <div class=\"row section-break\">\n <div class=\"col-xs-6 column-break\">\n\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Patient</label>\n </div>\n {% if doc.patient %}\n <div class=\"col-xs-7 value\">\n <strong>: </strong>{{doc.patient}}\n </div>\n {% else %}\n <div class=\"col-xs-7 value\">\n <strong>: </strong><em>Patient Name</em>\n </div>\n {%- endif -%}\n </div>\n\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Age</label>\n </div>\n <div class=\"col-xs-7 value\">\n <strong>: </strong> {{doc.patient_age}}\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Gender</label>\n </div>\n <div class=\"col-xs-7 value\">\n <strong>: </strong> {{doc.patient_sex}}\n </div>\n </div>\n\n </div>\n\n <div class=\"col-xs-6 column-break\">\n\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Practitioner</label>\n </div>\n {% if doc.practitioner %}\n <div class=\"col-xs-7 text-left value\">\n <strong>: </strong>{{doc.practitioner}}\n </div>\n {%- endif -%}\n </div>\n\n {% if doc.sample_date %}\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Sample Date</label>\n </div>\n <div class=\"col-xs-7 text-left value\">\n <strong>: </strong>{{doc.sample_date}}\n </div>\n </div>\n {%- endif -%}\n\n {% if doc.result_date %}\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Result Date</label>\n </div>\n <div class=\"col-xs-7 text-left value\">\n <strong>: </strong>{{doc.result_date}}\n </div>\n </div>\n {%- endif -%}\n\n </div>\n\n </div>\n\n <div align=\"center\">\n <hr><h4 class=\"text-uppercase\"><b><u>Department of {{doc.department}}</u></b></h4>\n </div>\n\n <table class=\"table\">\n <tbody>\n {%- if doc.normal_test_items -%}\n <tr>\n <th>Name of Test</th>\n <th class=\"text-left\">Result</th>\n <th class=\"text-right\">Normal Range</th>\n </tr>\n\n {%- if doc.normal_test_items|length > 1 %}\n <tr><td style=\"width: 40%;\"> <b>{{ doc.lab_test_name }}</b> </td><td></td></tr>\n {%- endif -%}\n\n {%- for row in doc.normal_test_items -%}\n <tr>\n <td style=\"width: 40%;border:none;\">\n {%- if doc.normal_test_items|length > 1 %}  {%- endif -%}\n {%- if row.lab_test_name -%}<b>{{ row.lab_test_name }}</b>\n {%- else -%}   {%- endif -%}\n {%- if row.lab_test_event -%}   {{ row.lab_test_event }}{%- endif -%}\n </td>\n\n <td style=\"width: 20%;text-align: left;border:none;\">\n {%- if row.result_value -%}{{ row.result_value }}{%- endif -%} \n {%- if row.lab_test_uom -%}{{ row.lab_test_uom }}{%- endif -%}\n </td>\n\n <td style=\"width: 30%;text-align: right;border:none;\">\n <div style=\"border: 0px;\">\n {%- if row.normal_range -%}{{ row.normal_range }}{%- endif -%}\n </div>\n </td>\n </tr>\n\n {%- endfor -%}\n {%- endif -%}\n </tbody>\n </table>\n\n <table class=\"table\">\n <tbody>\n {%- if doc.special_test_items -%}\n <tr>\n <th>Name of Test</th>\n <th class=\"text-left\">Result</th>\n </tr>\n <tr><td style=\"width: 30%;border:none;\"> <b>{{ doc.lab_test_name }}</b> </td><td></td></tr>\n {%- for row in doc.special_test_items -%}\n <tr>\n <td style=\"width: 30%;border:none;\">   {{ row.lab_test_particulars }} </td>\n <td style=\"width: 70%;text-align: left;border:none;\">\n {%- if row.result_value -%}{{ row.result_value }}{%- endif -%}\n </td>\n </tr>\n\n {%- endfor -%}\n {%- endif -%}\n\n {%- if doc.sensitivity_test_items -%}\n <tr>\n <th>Antibiotic</th>\n <th class=\"text-left\">Sensitivity</th>\n </tr>\n {%- for row in doc.sensitivity_test_items -%}\n <tr>\n <td style=\"width: 30%;border:none;\"> {{ row.antibiotic }} </td>\n <td style=\"width: 70%;text-align: left;border:none;\">{{ row.antibiotic_sensitivity }}</td>\n </tr>\n\n {%- endfor -%}\n {%- endif -%}\n\n </tbody>\n </table>\n {%- endif -%}\n\n <div align=\"right\">\n {%- if (frappe.db.get_value(\"Healthcare Settings\", \"None\", \"employee_name_and_designation_in_print\") == '1') -%}\n <h6 class=\"text-uppercase\"><b>{{doc.employee_name}}</b></h6>\n <h6 class=\"text-uppercase\"><b>{{doc.employee_designation}}</b></h6>\n {%- else -%}\n <h6 ><b>{{frappe.db.get_value(\"Healthcare Settings\", \"None\", \"custom_signature_in_print\") }}</b></h6>\n {%- endif -%}\n </div>\n</div>\n",
+ "idx": 0,
+ "line_breaks": 0,
+ "modified": "2018-09-04 12:03:47.066918",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Lab Test Print",
+ "owner": "Administrator",
+ "print_format_builder": 0,
+ "print_format_type": "Server",
+ "show_section_headings": 0,
"standard": "Yes"
}
\ No newline at end of file
diff --git a/erpnext/healthcare/page/appointment_analytic/__init__.py b/erpnext/healthcare/report/patient_appointment_analytics/__init__.py
similarity index 100%
copy from erpnext/healthcare/page/appointment_analytic/__init__.py
copy to erpnext/healthcare/report/patient_appointment_analytics/__init__.py
diff --git a/erpnext/healthcare/report/patient_appointment_analytics/patient_appointment_analytics.js b/erpnext/healthcare/report/patient_appointment_analytics/patient_appointment_analytics.js
new file mode 100644
index 0000000..18d252e
--- /dev/null
+++ b/erpnext/healthcare/report/patient_appointment_analytics/patient_appointment_analytics.js
@@ -0,0 +1,128 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports['Patient Appointment Analytics'] = {
+ "filters": [
+ {
+ fieldname: 'tree_type',
+ label: __('Tree Type'),
+ fieldtype: 'Select',
+ options: ['Healthcare Practitioner', 'Medical Department'],
+ default: 'Healthcare Practitioner',
+ reqd: 1
+ },
+ {
+ fieldname: 'status',
+ label: __('Appointment Status'),
+ fieldtype: 'Select',
+ options:[
+ {label: __('Scheduled'), value: 'Scheduled'},
+ {label: __('Open'), value: 'Open'},
+ {label: __('Closed'), value: 'Closed'},
+ {label: __('Expired'), value: 'Expired'},
+ {label: __('Cancelled'), value: 'Cancelled'}
+ ]
+ },
+ {
+ fieldname: 'appointment_type',
+ label: __('Appointment Type'),
+ fieldtype: 'Link',
+ options: 'Appointment Type'
+ },
+ {
+ fieldname: 'practitioner',
+ label: __('Healthcare Practitioner'),
+ fieldtype: 'Link',
+ options: 'Healthcare Practitioner'
+ },
+ {
+ fieldname: 'department',
+ label: __('Medical Department'),
+ fieldtype: 'Link',
+ options: 'Medical Department'
+ },
+ {
+ fieldname: 'from_date',
+ label: __('From Date'),
+ fieldtype: 'Date',
+ default: frappe.defaults.get_user_default('year_start_date'),
+ reqd: 1
+ },
+ {
+ fieldname: 'to_date',
+ label: __('To Date'),
+ fieldtype: 'Date',
+ default: frappe.defaults.get_user_default('year_end_date'),
+ reqd: 1
+ },
+ {
+ fieldname: 'range',
+ label: __('Range'),
+ fieldtype: 'Select',
+ options:[
+ {label: __('Weekly'), value: 'Weekly'},
+ {label: __('Monthly'), value: 'Monthly'},
+ {label: __('Quarterly'), value: 'Quarterly'},
+ {label: __('Yearly'), value: 'Yearly'}
+ ],
+ default: 'Monthly',
+ reqd: 1
+ }
+ ],
+ after_datatable_render: function(datatable_obj) {
+ $(datatable_obj.wrapper).find(".dt-row-0").find('input[type=checkbox]').click();
+ },
+ get_datatable_options(options) {
+ return Object.assign(options, {
+ checkboxColumn: true,
+ events: {
+ onCheckRow: function(data) {
+ row_name = data[2].content;
+ length = data.length;
+
+ row_values = data.slice(3,length-1).map(function (column) {
+ return column.content;
+ })
+
+ entry = {
+ 'name': row_name,
+ 'values': row_values
+ }
+
+ let raw_data = frappe.query_report.chart.data;
+ let new_datasets = raw_data.datasets;
+
+ let found = false;
+ for (let i=0; i < new_datasets.length;i++) {
+ if (new_datasets[i].name == row_name) {
+ found = true;
+ new_datasets.splice(i,1);
+ break;
+ }
+ }
+
+ if (!found) {
+ new_datasets.push(entry);
+ }
+
+ let new_data = {
+ labels: raw_data.labels,
+ datasets: new_datasets
+ }
+
+ setTimeout(() => {
+ frappe.query_report.chart.update(new_data)
+ }, 500)
+
+
+ setTimeout(() => {
+ frappe.query_report.chart.draw(true);
+ }, 1000)
+
+ frappe.query_report.raw_chart_data = new_data;
+ },
+ }
+ })
+ },
+};
diff --git a/erpnext/healthcare/report/patient_appointment_analytics/patient_appointment_analytics.json b/erpnext/healthcare/report/patient_appointment_analytics/patient_appointment_analytics.json
new file mode 100644
index 0000000..64750c0
--- /dev/null
+++ b/erpnext/healthcare/report/patient_appointment_analytics/patient_appointment_analytics.json
@@ -0,0 +1,36 @@
+{
+ "add_total_row": 1,
+ "creation": "2020-03-02 15:13:16.273493",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "modified": "2020-03-02 15:13:16.273493",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Patient Appointment Analytics",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Patient Appointment",
+ "report_name": "Patient Appointment Analytics",
+ "report_type": "Script Report",
+ "roles": [
+ {
+ "role": "Healthcare Administrator"
+ },
+ {
+ "role": "LabTest Approver"
+ },
+ {
+ "role": "Physician"
+ },
+ {
+ "role": "Nursing User"
+ },
+ {
+ "role": "Laboratory User"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/report/patient_appointment_analytics/patient_appointment_analytics.py b/erpnext/healthcare/report/patient_appointment_analytics/patient_appointment_analytics.py
new file mode 100644
index 0000000..9c35dbb
--- /dev/null
+++ b/erpnext/healthcare/report/patient_appointment_analytics/patient_appointment_analytics.py
@@ -0,0 +1,194 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.utils import getdate, flt, add_to_date, add_days
+from frappe import _ , scrub
+from six import iteritems
+from erpnext.accounts.utils import get_fiscal_year
+
+def execute(filters=None):
+ return Analytics(filters).run()
+
+class Analytics(object):
+ def __init__(self, filters=None):
+ """Patient Appointment Analytics Report."""
+ self.filters = frappe._dict(filters or {})
+ self.months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
+ self.get_period_date_ranges()
+
+ def run(self):
+ self.get_columns()
+ self.get_data()
+ self.get_chart_data()
+
+ return self.columns, self.data, None, self.chart
+
+ def get_period_date_ranges(self):
+ from dateutil.relativedelta import relativedelta, MO
+ from_date, to_date = getdate(self.filters.from_date), getdate(self.filters.to_date)
+
+ increment = {
+ 'Monthly': 1,
+ 'Quarterly': 3,
+ 'Half-Yearly': 6,
+ 'Yearly': 12
+ }.get(self.filters.range, 1)
+
+ if self.filters.range in ['Monthly', 'Quarterly']:
+ from_date = from_date.replace(day=1)
+ elif self.filters.range == 'Yearly':
+ from_date = get_fiscal_year(from_date)[1]
+ else:
+ from_date = from_date + relativedelta(from_date, weekday=MO(-1))
+
+ self.periodic_daterange = []
+ for dummy in range(1, 53):
+ if self.filters.range == 'Weekly':
+ period_end_date = add_days(from_date, 6)
+ else:
+ period_end_date = add_to_date(from_date, months=increment, days=-1)
+
+ if period_end_date > to_date:
+ period_end_date = to_date
+
+ self.periodic_daterange.append(period_end_date)
+
+ from_date = add_days(period_end_date, 1)
+ if period_end_date == to_date:
+ break
+
+ def get_columns(self):
+ self.columns = []
+
+ if self.filters.tree_type == 'Healthcare Practitioner':
+ self.columns.append({
+ 'label': _('Healthcare Practitioner'),
+ 'options': 'Healthcare Practitioner',
+ 'fieldname': 'practitioner',
+ 'fieldtype': 'Link',
+ 'width': 200
+ })
+
+ elif self.filters.tree_type == 'Medical Department':
+ self.columns.append({
+ 'label': _('Medical Department'),
+ 'fieldname': 'department',
+ 'fieldtype': 'Link',
+ 'options': 'Medical Department',
+ 'width': 150
+ })
+
+ for end_date in self.periodic_daterange:
+ period = self.get_period(end_date)
+ self.columns.append({
+ 'label': _(period),
+ 'fieldname': scrub(period),
+ 'fieldtype': 'Int',
+ 'width': 120
+ })
+
+ self.columns.append({
+ 'label': _('Total'),
+ 'fieldname': 'total',
+ 'fieldtype': 'Int',
+ 'width': 120
+ })
+
+ def get_data(self):
+ if self.filters.tree_type == 'Healthcare Practitioner':
+ self.get_appointments_based_on_healthcare_practitioner()
+ self.get_rows()
+
+ elif self.filters.tree_type == 'Medical Department':
+ self.get_appointments_based_on_medical_department()
+ self.get_rows()
+
+ def get_period(self, appointment_date):
+ if self.filters.range == 'Weekly':
+ period = 'Week ' + str(appointment_date.isocalendar()[1])
+ elif self.filters.range == 'Monthly':
+ period = str(self.months[appointment_date.month - 1])
+ elif self.filters.range == 'Quarterly':
+ period = 'Quarter ' + str(((appointment_date.month - 1) // 3) + 1)
+ else:
+ year = get_fiscal_year(appointment_date, company=self.filters.company)
+ period = str(year[0])
+
+ if getdate(self.filters.from_date).year != getdate(self.filters.to_date).year:
+ period += ' ' + str(appointment_date.year)
+
+ return period
+
+ def get_appointments_based_on_healthcare_practitioner(self):
+ filters = self.get_common_filters()
+
+ self.entries = frappe.db.get_all('Patient Appointment',
+ fields=['appointment_date', 'name', 'patient', 'practitioner'],
+ filters=filters
+ )
+
+ def get_appointments_based_on_medical_department(self):
+ filters = self.get_common_filters()
+ if not filters.get('department'):
+ filters['department'] = ('!=', '')
+
+ self.entries = frappe.db.get_all('Patient Appointment',
+ fields=['appointment_date', 'name', 'patient', 'practitioner', 'department'],
+ filters=filters
+ )
+
+ def get_common_filters(self):
+ filters = {}
+ filters['appointment_date'] = ('between', [self.filters.from_date, self.filters.to_date])
+ for entry in ['appointment_type', 'practitioner', 'department', 'status']:
+ if self.filters.get(entry):
+ filters[entry] = self.filters.get(entry)
+
+ return filters
+
+ def get_rows(self):
+ self.data = []
+ self.get_periodic_data()
+
+ for entity, period_data in iteritems(self.appointment_periodic_data):
+ if self.filters.tree_type == 'Healthcare Practitioner':
+ row = {'practitioner': entity}
+ elif self.filters.tree_type == 'Medical Department':
+ row = {'department': entity}
+
+ total = 0
+ for end_date in self.periodic_daterange:
+ period = self.get_period(end_date)
+ amount = flt(period_data.get(period, 0.0))
+ row[scrub(period)] = amount
+ total += amount
+
+ row['total'] = total
+
+ self.data.append(row)
+
+ def get_periodic_data(self):
+ self.appointment_periodic_data = frappe._dict()
+
+ for d in self.entries:
+ period = self.get_period(d.get('appointment_date'))
+ if self.filters.tree_type == 'Healthcare Practitioner':
+ self.appointment_periodic_data.setdefault(d.practitioner, frappe._dict()).setdefault(period, 0.0)
+ self.appointment_periodic_data[d.practitioner][period] += 1
+
+ elif self.filters.tree_type == 'Medical Department':
+ self.appointment_periodic_data.setdefault(d.department, frappe._dict()).setdefault(period, 0.0)
+ self.appointment_periodic_data[d.department][period] += 1
+
+ def get_chart_data(self):
+ length = len(self.columns)
+ labels = [d.get("label") for d in self.columns[1:length - 1]]
+ self.chart = {
+ "data": {
+ 'labels': labels,
+ 'datasets': []
+ },
+ "type": "line"
+ }
\ No newline at end of file
diff --git a/erpnext/healthcare/utils.py b/erpnext/healthcare/utils.py
index 97bb98f..246242a 100644
--- a/erpnext/healthcare/utils.py
+++ b/erpnext/healthcare/utils.py
@@ -4,417 +4,471 @@
from __future__ import unicode_literals
import frappe
-import datetime
from frappe import _
import math
-from frappe.utils import time_diff_in_hours, rounded, getdate, add_days
+from frappe.utils import time_diff_in_hours, rounded
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_income_account
-from erpnext.healthcare.doctype.fee_validity.fee_validity import create_fee_validity, update_fee_validity
+from erpnext.healthcare.doctype.fee_validity.fee_validity import create_fee_validity
from erpnext.healthcare.doctype.lab_test.lab_test import create_multiple
@frappe.whitelist()
def get_healthcare_services_to_invoice(patient):
- patient = frappe.get_doc("Patient", patient)
+ patient = frappe.get_doc('Patient', patient)
if patient:
- if patient.customer:
- item_to_invoice = []
- patient_appointments = frappe.get_list("Patient Appointment",{'patient': patient.name, 'invoiced': False},
- order_by="appointment_date")
- if patient_appointments:
- fee_validity_details = []
- valid_days = frappe.db.get_value("Healthcare Settings", None, "valid_days")
- max_visit = frappe.db.get_value("Healthcare Settings", None, "max_visit")
- for patient_appointment in patient_appointments:
- patient_appointment_obj = frappe.get_doc("Patient Appointment", patient_appointment['name'])
+ validate_customer_created(patient)
+ items_to_invoice = []
+ patient_appointments = frappe.get_list(
+ 'Patient Appointment',
+ fields='*',
+ filters={'patient': patient.name, 'invoiced': 0},
+ order_by='appointment_date'
+ )
+ if patient_appointments:
+ items_to_invoice = get_fee_validity(patient_appointments)
- if patient_appointment_obj.procedure_template:
- if frappe.db.get_value("Clinical Procedure Template", patient_appointment_obj.procedure_template, "is_billable") == 1:
- item_to_invoice.append({'reference_type': 'Patient Appointment', 'reference_name': patient_appointment_obj.name, 'service': patient_appointment_obj.procedure_template})
- else:
- practitioner_exist_in_list = False
- skip_invoice = False
- if fee_validity_details:
- for validity in fee_validity_details:
- if validity['practitioner'] == patient_appointment_obj.practitioner:
- practitioner_exist_in_list = True
- if validity['valid_till'] >= patient_appointment_obj.appointment_date:
- validity['visits'] = validity['visits']+1
- if int(max_visit) > validity['visits']:
- skip_invoice = True
- if not skip_invoice:
- validity['visits'] = 1
- validity['valid_till'] = patient_appointment_obj.appointment_date + datetime.timedelta(days=int(valid_days))
- if not practitioner_exist_in_list:
- valid_till = patient_appointment_obj.appointment_date + datetime.timedelta(days=int(valid_days))
- visits = 0
- validity_exist = validity_exists(patient_appointment_obj.practitioner, patient_appointment_obj.patient)
- if validity_exist:
- fee_validity = frappe.get_doc("Fee Validity", validity_exist[0][0])
- valid_till = fee_validity.valid_till
- visits = fee_validity.visited
- fee_validity_details.append({'practitioner': patient_appointment_obj.practitioner,
- 'valid_till': valid_till, 'visits': visits})
+ encounters = get_encounters_to_invoice(patient)
+ lab_tests = get_lab_tests_to_invoice(patient)
+ clinical_procedures = get_clinical_procedures_to_invoice(patient)
+ inpatient_services = get_inpatient_services_to_invoice(patient)
- if not skip_invoice:
- practitioner_charge = 0
- income_account = None
- service_item = None
- if patient_appointment_obj.practitioner:
- service_item, practitioner_charge = service_item_and_practitioner_charge(patient_appointment_obj)
- income_account = get_income_account(patient_appointment_obj.practitioner, patient_appointment_obj.company)
- item_to_invoice.append({'reference_type': 'Patient Appointment', 'reference_name': patient_appointment_obj.name,
- 'service': service_item, 'rate': practitioner_charge,
- 'income_account': income_account})
+ items_to_invoice += encounters + lab_tests + clinical_procedures + inpatient_services
+ return items_to_invoice
- encounters = frappe.get_list("Patient Encounter", {'patient': patient.name, 'invoiced': False, 'docstatus': 1})
- if encounters:
- for encounter in encounters:
- encounter_obj = frappe.get_doc("Patient Encounter", encounter['name'])
- if not encounter_obj.appointment:
- practitioner_charge = 0
- income_account = None
- service_item = None
- if encounter_obj.practitioner:
- service_item, practitioner_charge = service_item_and_practitioner_charge(encounter_obj)
- income_account = get_income_account(encounter_obj.practitioner, encounter_obj.company)
+def validate_customer_created(patient):
+ if not frappe.db.get_value('Patient', patient.name, 'customer'):
+ msg = _("Please set a Customer linked to the Patient")
+ msg += " <b><a href='#Form/Patient/{0}'>{0}</a></b>".format(patient.name)
+ frappe.throw(msg, title=_('Customer Not Found'))
- item_to_invoice.append({'reference_type': 'Patient Encounter', 'reference_name': encounter_obj.name,
- 'service': service_item, 'rate': practitioner_charge,
- 'income_account': income_account})
+def get_fee_validity(patient_appointments):
+ if not frappe.db.get_single_value('Healthcare Settings', 'enable_free_follow_ups'):
+ return
- lab_tests = frappe.get_list("Lab Test", {'patient': patient.name, 'invoiced': False, 'docstatus': 1})
- if lab_tests:
- for lab_test in lab_tests:
- lab_test_obj = frappe.get_doc("Lab Test", lab_test['name'])
- if frappe.db.get_value("Lab Test Template", lab_test_obj.template, "is_billable") == 1:
- item_to_invoice.append({'reference_type': 'Lab Test', 'reference_name': lab_test_obj.name,
- 'service': frappe.db.get_value("Lab Test Template", lab_test_obj.template, "item")})
-
- lab_rxs = frappe.db.sql("""select lp.name from `tabPatient Encounter` et, `tabLab Prescription` lp
- where et.patient=%s and lp.parent=et.name and lp.lab_test_created=0 and lp.invoiced=0""", (patient.name))
- if lab_rxs:
- for lab_rx in lab_rxs:
- rx_obj = frappe.get_doc("Lab Prescription", lab_rx[0])
- if rx_obj.lab_test_code and (frappe.db.get_value("Lab Test Template", rx_obj.lab_test_code, "is_billable") == 1):
- item_to_invoice.append({'reference_type': 'Lab Prescription', 'reference_name': rx_obj.name,
- 'service': frappe.db.get_value("Lab Test Template", rx_obj.lab_test_code, "item")})
-
- procedures = frappe.get_list("Clinical Procedure", {'patient': patient.name, 'invoiced': False})
- if procedures:
- for procedure in procedures:
- procedure_obj = frappe.get_doc("Clinical Procedure", procedure['name'])
- if not procedure_obj.appointment:
- if procedure_obj.procedure_template and (frappe.db.get_value("Clinical Procedure Template", procedure_obj.procedure_template, "is_billable") == 1):
- item_to_invoice.append({'reference_type': 'Clinical Procedure', 'reference_name': procedure_obj.name,
- 'service': frappe.db.get_value("Clinical Procedure Template", procedure_obj.procedure_template, "item")})
-
- procedure_rxs = frappe.db.sql("""select pp.name from `tabPatient Encounter` et,
- `tabProcedure Prescription` pp where et.patient=%s and pp.parent=et.name and
- pp.procedure_created=0 and pp.invoiced=0 and pp.appointment_booked=0""", (patient.name))
- if procedure_rxs:
- for procedure_rx in procedure_rxs:
- rx_obj = frappe.get_doc("Procedure Prescription", procedure_rx[0])
- if frappe.db.get_value("Clinical Procedure Template", rx_obj.procedure, "is_billable") == 1:
- item_to_invoice.append({'reference_type': 'Procedure Prescription', 'reference_name': rx_obj.name,
- 'service': frappe.db.get_value("Clinical Procedure Template", rx_obj.procedure, "item")})
-
- procedures = frappe.get_list("Clinical Procedure",
- {'patient': patient.name, 'invoice_separately_as_consumables': True, 'consumption_invoiced': False,
- 'consume_stock': True, 'status': 'Completed'})
- if procedures:
- service_item = get_healthcare_service_item('clinical_procedure_consumable_item')
- if not service_item:
- msg = _(("Please Configure {0} in ").format("Clinical Procedure Consumable Item") \
- + """<b><a href="#Form/Healthcare Settings">Healthcare Settings</a></b>""")
- frappe.throw(msg)
- for procedure in procedures:
- procedure_obj = frappe.get_doc("Clinical Procedure", procedure['name'])
- item_to_invoice.append({'reference_type': 'Clinical Procedure', 'reference_name': procedure_obj.name,
- 'service': service_item, 'rate': procedure_obj.consumable_total_amount, 'description': procedure_obj.consumption_details})
-
- inpatient_services = frappe.db.sql("""select io.name, io.parent from `tabInpatient Record` ip,
- `tabInpatient Occupancy` io where ip.patient=%s and io.parent=ip.name and
- io.left=1 and io.invoiced=0""", (patient.name))
- if inpatient_services:
- for inpatient_service in inpatient_services:
- inpatient_occupancy = frappe.get_doc("Inpatient Occupancy", inpatient_service[0])
- service_unit_type = frappe.get_doc("Healthcare Service Unit Type", frappe.db.get_value("Healthcare Service Unit", inpatient_occupancy.service_unit, "service_unit_type"))
- if service_unit_type and service_unit_type.is_billable == 1:
- hours_occupied = time_diff_in_hours(inpatient_occupancy.check_out, inpatient_occupancy.check_in)
- qty = 0.5
- if hours_occupied > 0:
- actual_qty = hours_occupied / service_unit_type.no_of_hours
- floor = math.floor(actual_qty)
- decimal_part = actual_qty - floor
- if decimal_part > 0.5:
- qty = rounded(floor + 1, 1)
- elif decimal_part < 0.5 and decimal_part > 0:
- qty = rounded(floor + 0.5, 1)
- if qty <= 0:
- qty = 0.5
- item_to_invoice.append({'reference_type': 'Inpatient Occupancy', 'reference_name': inpatient_occupancy.name,
- 'service': service_unit_type.item, 'qty': qty})
-
- return item_to_invoice
+ items_to_invoice = []
+ for appointment in patient_appointments:
+ if appointment.procedure_template:
+ if frappe.db.get_value('Clinical Procedure Template', appointment.procedure_template, 'is_billable'):
+ items_to_invoice.append({
+ 'reference_type': 'Patient Appointment',
+ 'reference_name': appointment.name,
+ 'service': appointment.procedure_template
+ })
else:
- frappe.throw(_("The Patient {0} do not have customer refrence to invoice").format(patient.name))
+ fee_validity = frappe.db.exists('Fee Validity Reference', {'appointment': appointment.name})
+ if not fee_validity:
+ practitioner_charge = 0
+ income_account = None
+ service_item = None
+ if appointment.practitioner:
+ service_item, practitioner_charge = get_service_item_and_practitioner_charge(appointment)
+ income_account = get_income_account(appointment.practitioner, appointment.company)
+ items_to_invoice.append({
+ 'reference_type': 'Patient Appointment',
+ 'reference_name': appointment.name,
+ 'service': service_item,
+ 'rate': practitioner_charge,
+ 'income_account': income_account
+ })
-def service_item_and_practitioner_charge(doc):
- is_ip = doc_is_ip(doc)
- if is_ip:
- service_item = get_practitioner_service_item(doc.practitioner, "inpatient_visit_charge_item")
+ return items_to_invoice
+
+
+def get_encounters_to_invoice(patient):
+ encounters_to_invoice = []
+ encounters = frappe.get_list(
+ 'Patient Encounter',
+ fields=['*'],
+ filters={'patient': patient.name, 'invoiced': False, 'docstatus': 1}
+ )
+ if encounters:
+ for encounter in encounters:
+ if not encounter.appointment:
+ practitioner_charge = 0
+ income_account = None
+ service_item = None
+ if encounter.practitioner:
+ service_item, practitioner_charge = get_service_item_and_practitioner_charge(encounter)
+ income_account = get_income_account(encounter.practitioner, encounter.company)
+
+ encounters_to_invoice.append({
+ 'reference_type': 'Patient Encounter',
+ 'reference_name': encounter.name,
+ 'service': service_item,
+ 'rate': practitioner_charge,
+ 'income_account': income_account
+ })
+
+ return encounters_to_invoice
+
+
+def get_lab_tests_to_invoice(patient):
+ lab_tests_to_invoice = []
+ lab_tests = frappe.get_list(
+ 'Lab Test',
+ fields=['name', 'template'],
+ filters={'patient': patient.name, 'invoiced': False, 'docstatus': 1}
+ )
+ for lab_test in lab_tests:
+ item, is_billable = frappe.get_cached_value('Lab Test Template', lab_test.lab_test_code, ['item', 'is_billable'])
+ if is_billable:
+ lab_tests_to_invoice.append({
+ 'reference_type': 'Lab Test',
+ 'reference_name': lab_test.name,
+ 'service': item
+ })
+
+ lab_prescriptions = frappe.db.sql(
+ '''
+ SELECT
+ lp.name, lp.lab_test_code
+ FROM
+ `tabPatient Encounter` et, `tabLab Prescription` lp
+ WHERE
+ et.patient=%s
+ and lp.parent=et.name
+ and lp.lab_test_created=0
+ and lp.invoiced=0
+ ''', (patient.name), as_dict=1)
+
+ for prescription in lab_prescriptions:
+ item, is_billable = frappe.get_cached_value('Lab Test Template', prescription.lab_test_code, ['item', 'is_billable'])
+ if prescription.lab_test_code and is_billable:
+ lab_tests_to_invoice.append({
+ 'reference_type': 'Lab Prescription',
+ 'reference_name': prescription.name,
+ 'service': item
+ })
+
+ return lab_tests_to_invoice
+
+
+def get_clinical_procedures_to_invoice(patient):
+ clinical_procedures_to_invoice = []
+ procedures = frappe.get_list(
+ 'Clinical Procedure',
+ fields='*',
+ filters={'patient': patient.name, 'invoiced': False}
+ )
+ for procedure in procedures:
+ if not procedure.appointment:
+ item, is_billable = frappe.get_cached_value('Clinical Procedure Template', procedure.procedure_template, ['item', 'is_billable'])
+ if procedure.procedure_template and is_billable:
+ clinical_procedures_to_invoice.append({
+ 'reference_type': 'Clinical Procedure',
+ 'reference_name': procedure.name,
+ 'service': item
+ })
+
+ # consumables
+ if procedure.invoice_separately_as_consumables and procedure.consume_stock \
+ and procedure.status == 'Completed' and not procedure.consumption_invoiced:
+
+ service_item = get_healthcare_service_item('clinical_procedure_consumable_item')
+ if not service_item:
+ msg = _('Please Configure Clinical Procedure Consumable Item in ')
+ msg += '''<b><a href='#Form/Healthcare Settings'>Healthcare Settings</a></b>'''
+ frappe.throw(msg, title=_('Missing Configuration'))
+
+ clinical_procedures_to_invoice.append({
+ 'reference_type': 'Clinical Procedure',
+ 'reference_name': procedure.name,
+ 'service': service_item,
+ 'rate': procedure.consumable_total_amount,
+ 'description': procedure.consumption_details
+ })
+
+ procedure_prescriptions = frappe.db.sql(
+ '''
+ SELECT
+ pp.name, pp.procedure
+ FROM
+ `tabPatient Encounter` et, `tabProcedure Prescription` pp
+ WHERE
+ et.patient=%s
+ and pp.parent=et.name
+ and pp.procedure_created=0
+ and pp.invoiced=0
+ and pp.appointment_booked=0
+ ''', (patient.name), as_dict=1)
+
+ for prescription in procedure_prescriptions:
+ item, is_billable = frappe.get_cached_value('Clinical Procedure Template', prescription.procedure, ['item', 'is_billable'])
+ if is_billable:
+ clinical_procedures_to_invoice.append({
+ 'reference_type': 'Procedure Prescription',
+ 'reference_name': prescription.name,
+ 'service': item
+ })
+
+ return clinical_procedures_to_invoice
+
+
+def get_inpatient_services_to_invoice(patient):
+ services_to_invoice = []
+ inpatient_services = frappe.db.sql(
+ '''
+ SELECT
+ io.*
+ FROM
+ `tabInpatient Record` ip, `tabInpatient Occupancy` io
+ WHERE
+ ip.patient=%s
+ and io.parent=ip.name
+ and io.left=1
+ and io.invoiced=0
+ ''', (patient.name), as_dict=1)
+
+ for inpatient_occupancy in inpatient_services:
+ service_unit_type = frappe.db.get_value('Healthcare Service Unit', inpatient_occupancy.service_unit, 'service_unit_type')
+ service_unit_type = frappe.get_cached_doc('Healthcare Service Unit Type', service_unit_type)
+ if service_unit_type and service_unit_type.is_billable:
+ hours_occupied = time_diff_in_hours(inpatient_occupancy.check_out, inpatient_occupancy.check_in)
+ qty = 0.5
+ if hours_occupied > 0:
+ actual_qty = hours_occupied / service_unit_type.no_of_hours
+ floor = math.floor(actual_qty)
+ decimal_part = actual_qty - floor
+ if decimal_part > 0.5:
+ qty = rounded(floor + 1, 1)
+ elif decimal_part < 0.5 and decimal_part > 0:
+ qty = rounded(floor + 0.5, 1)
+ if qty <= 0:
+ qty = 0.5
+ services_to_invoice.append({
+ 'reference_type': 'Inpatient Occupancy',
+ 'reference_name': inpatient_occupancy.name,
+ 'service': service_unit_type.item, 'qty': qty
+ })
+
+ return services_to_invoice
+
+
+def get_service_item_and_practitioner_charge(doc):
+ is_inpatient = doc.inpatient_record
+ if is_inpatient:
+ service_item = get_practitioner_service_item(doc.practitioner, 'inpatient_visit_charge_item')
if not service_item:
- service_item = get_healthcare_service_item("inpatient_visit_charge_item")
+ service_item = get_healthcare_service_item('inpatient_visit_charge_item')
else:
- service_item = get_practitioner_service_item(doc.practitioner, "op_consulting_charge_item")
+ service_item = get_practitioner_service_item(doc.practitioner, 'op_consulting_charge_item')
if not service_item:
- service_item = get_healthcare_service_item("op_consulting_charge_item")
+ service_item = get_healthcare_service_item('op_consulting_charge_item')
if not service_item:
- throw_config_service_item(is_ip)
+ throw_config_service_item(is_inpatient)
- practitioner_charge = get_practitioner_charge(doc.practitioner, is_ip)
+ practitioner_charge = get_practitioner_charge(doc.practitioner, is_inpatient)
if not practitioner_charge:
- throw_config_practitioner_charge(is_ip, doc.practitioner)
+ throw_config_practitioner_charge(is_inpatient, doc.practitioner)
return service_item, practitioner_charge
-def throw_config_service_item(is_ip):
- service_item_lable = "Out Patient Consulting Charge Item"
- if is_ip:
- service_item_lable = "Inpatient Visit Charge Item"
- msg = _(("Please Configure {0} in ").format(service_item_lable) \
- + """<b><a href="#Form/Healthcare Settings">Healthcare Settings</a></b>""")
- frappe.throw(msg)
+def throw_config_service_item(is_inpatient):
+ service_item_label = _('Out Patient Consulting Charge Item')
+ if is_inpatient:
+ service_item_label = _('Inpatient Visit Charge Item')
-def throw_config_practitioner_charge(is_ip, practitioner):
- charge_name = "OP Consulting Charge"
- if is_ip:
- charge_name = "Inpatient Visit Charge"
+ msg = _(('Please Configure {0} in ').format(service_item_label) \
+ + '''<b><a href='#Form/Healthcare Settings'>Healthcare Settings</a></b>''')
+ frappe.throw(msg, title=_('Missing Configuration'))
- msg = _(("Please Configure {0} for Healthcare Practitioner").format(charge_name) \
- + """ <b><a href="#Form/Healthcare Practitioner/{0}">{0}</a></b>""".format(practitioner))
- frappe.throw(msg)
+
+def throw_config_practitioner_charge(is_inpatient, practitioner):
+ charge_name = _('OP Consulting Charge')
+ if is_inpatient:
+ charge_name = _('Inpatient Visit Charge')
+
+ msg = _(('Please Configure {0} for Healthcare Practitioner').format(charge_name) \
+ + ''' <b><a href='#Form/Healthcare Practitioner/{0}'>{0}</a></b>'''.format(practitioner))
+ frappe.throw(msg, title=_('Missing Configuration'))
+
def get_practitioner_service_item(practitioner, service_item_field):
- return frappe.db.get_value("Healthcare Practitioner", practitioner, service_item_field)
+ return frappe.db.get_value('Healthcare Practitioner', practitioner, service_item_field)
+
def get_healthcare_service_item(service_item_field):
- return frappe.db.get_value("Healthcare Settings", None, service_item_field)
+ return frappe.db.get_single_value('Healthcare Settings', service_item_field)
-def doc_is_ip(doc):
- is_ip = False
- if doc.inpatient_record:
- is_ip = True
- return is_ip
-def get_practitioner_charge(practitioner, is_ip):
- if is_ip:
- practitioner_charge = frappe.db.get_value("Healthcare Practitioner", practitioner, "inpatient_visit_charge")
+def get_practitioner_charge(practitioner, is_inpatient):
+ if is_inpatient:
+ practitioner_charge = frappe.db.get_value('Healthcare Practitioner', practitioner, 'inpatient_visit_charge')
else:
- practitioner_charge = frappe.db.get_value("Healthcare Practitioner", practitioner, "op_consulting_charge")
+ practitioner_charge = frappe.db.get_value('Healthcare Practitioner', practitioner, 'op_consulting_charge')
if practitioner_charge:
return practitioner_charge
return False
+
def manage_invoice_submit_cancel(doc, method):
if doc.items:
for item in doc.items:
- if item.get("reference_dt") and item.get("reference_dn"):
- if frappe.get_meta(item.reference_dt).has_field("invoiced"):
+ if item.get('reference_dt') and item.get('reference_dn'):
+ if frappe.get_meta(item.reference_dt).has_field('invoiced'):
set_invoiced(item, method, doc.name)
- if method=="on_submit" and frappe.db.get_value("Healthcare Settings", None, "create_test_on_si_submit") == '1':
- create_multiple("Sales Invoice", doc.name)
+ if method=='on_submit' and frappe.db.get_single_value('Healthcare Settings', 'create_lab_test_on_si_submit'):
+ create_multiple('Sales Invoice', doc.name)
+
def set_invoiced(item, method, ref_invoice=None):
invoiced = False
- if(method=="on_submit"):
+ if method=='on_submit':
validate_invoiced_on_submit(item)
invoiced = True
if item.reference_dt == 'Clinical Procedure':
if get_healthcare_service_item('clinical_procedure_consumable_item') == item.item_code:
- frappe.db.set_value(item.reference_dt, item.reference_dn, "consumption_invoiced", invoiced)
+ frappe.db.set_value(item.reference_dt, item.reference_dn, 'consumption_invoiced', invoiced)
else:
- frappe.db.set_value(item.reference_dt, item.reference_dn, "invoiced", invoiced)
+ frappe.db.set_value(item.reference_dt, item.reference_dn, 'invoiced', invoiced)
else:
- frappe.db.set_value(item.reference_dt, item.reference_dn, "invoiced", invoiced)
+ frappe.db.set_value(item.reference_dt, item.reference_dn, 'invoiced', invoiced)
if item.reference_dt == 'Patient Appointment':
if frappe.db.get_value('Patient Appointment', item.reference_dn, 'procedure_template'):
- dt_from_appointment = "Clinical Procedure"
+ dt_from_appointment = 'Clinical Procedure'
else:
- manage_fee_validity(item.reference_dn, method, ref_invoice)
- dt_from_appointment = "Patient Encounter"
- manage_doc_for_appoitnment(dt_from_appointment, item.reference_dn, invoiced)
+ dt_from_appointment = 'Patient Encounter'
+ manage_doc_for_appointment(dt_from_appointment, item.reference_dn, invoiced)
elif item.reference_dt == 'Lab Prescription':
- manage_prescriptions(invoiced, item.reference_dt, item.reference_dn, "Lab Test", "lab_test_created")
+ manage_prescriptions(invoiced, item.reference_dt, item.reference_dn, 'Lab Test', 'lab_test_created')
elif item.reference_dt == 'Procedure Prescription':
- manage_prescriptions(invoiced, item.reference_dt, item.reference_dn, "Clinical Procedure", "procedure_created")
+ manage_prescriptions(invoiced, item.reference_dt, item.reference_dn, 'Clinical Procedure', 'procedure_created')
+
def validate_invoiced_on_submit(item):
if item.reference_dt == 'Clinical Procedure' and get_healthcare_service_item('clinical_procedure_consumable_item') == item.item_code:
- is_invoiced = frappe.db.get_value(item.reference_dt, item.reference_dn, "consumption_invoiced")
+ is_invoiced = frappe.db.get_value(item.reference_dt, item.reference_dn, 'consumption_invoiced')
else:
- is_invoiced = frappe.db.get_value(item.reference_dt, item.reference_dn, "invoiced")
- if is_invoiced == 1:
- frappe.throw(_("The item referenced by {0} - {1} is already invoiced"\
+ is_invoiced = frappe.db.get_value(item.reference_dt, item.reference_dn, 'invoiced')
+ if is_invoiced:
+ frappe.throw(_('The item referenced by {0} - {1} is already invoiced'\
).format(item.reference_dt, item.reference_dn))
+
def manage_prescriptions(invoiced, ref_dt, ref_dn, dt, created_check_field):
created = frappe.db.get_value(ref_dt, ref_dn, created_check_field)
- if created == 1:
+ if created:
# Fetch the doc created for the prescription
doc_created = frappe.db.get_value(dt, {'prescription': ref_dn})
frappe.db.set_value(dt, doc_created, 'invoiced', invoiced)
-def validity_exists(practitioner, patient):
- return frappe.db.exists({
- "doctype": "Fee Validity",
- "practitioner": practitioner,
- "patient": patient})
-def manage_fee_validity(appointment_name, method, ref_invoice=None):
- appointment_doc = frappe.get_doc("Patient Appointment", appointment_name)
- validity_exist = validity_exists(appointment_doc.practitioner, appointment_doc.patient)
- do_not_update = False
- visited = 0
- if validity_exist:
- fee_validity = frappe.get_doc("Fee Validity", validity_exist[0][0])
- # Check if the validity is valid
- if (fee_validity.valid_till >= appointment_doc.appointment_date):
- if (method == "on_cancel" and appointment_doc.status != "Closed"):
- if ref_invoice == fee_validity.ref_invoice:
- visited = fee_validity.visited - 1
- if visited < 0:
- visited = 0
- frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
- do_not_update = True
- elif (method == "on_submit" and fee_validity.visited < fee_validity.max_visit):
- visited = fee_validity.visited + 1
- frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
- do_not_update = True
- else:
- do_not_update = False
+def check_fee_validity(appointment):
+ if not frappe.db.get_single_value('Healthcare Settings', 'enable_free_follow_ups'):
+ return
- if not do_not_update:
- fee_validity = update_fee_validity(fee_validity, appointment_doc.appointment_date, ref_invoice)
- visited = fee_validity.visited
+ validity = frappe.db.exists('Fee Validity', {
+ 'practitioner': appointment.practitioner,
+ 'patient': appointment.patient,
+ 'valid_till': ('>=', appointment.appointment_date)
+ })
+ if not validity:
+ return
+
+ validity = frappe.get_doc('Fee Validity', validity)
+ return validity
+
+
+def manage_fee_validity(appointment):
+ fee_validity = check_fee_validity(appointment)
+ if fee_validity:
+ if appointment.status == 'Cancelled' and fee_validity.visited > 0:
+ fee_validity.visited -= 1
+ frappe.db.delete('Fee Validity Reference', {'appointment': appointment.name})
+ elif fee_validity.status == 'Completed':
+ return
+ else:
+ fee_validity.visited += 1
+ fee_validity.append('ref_appointments', {
+ 'appointment': appointment.name
+ })
+ fee_validity.save(ignore_permissions=True)
else:
- fee_validity = create_fee_validity(appointment_doc.practitioner, appointment_doc.patient, appointment_doc.appointment_date, ref_invoice)
- visited = fee_validity.visited
+ fee_validity = create_fee_validity(appointment)
+ return fee_validity
- # Mark All Patient Appointment invoiced = True in the validity range do not cross the max visit
- if (method == "on_cancel"):
- invoiced = True
- else:
- invoiced = False
- patient_appointments = appointments_valid_in_fee_validity(appointment_doc, invoiced)
- if patient_appointments and fee_validity:
- visit = visited
- for appointment in patient_appointments:
- if (method == "on_cancel" and appointment.status != "Closed"):
- if ref_invoice == fee_validity.ref_invoice:
- visited = visited - 1
- if visited < 0:
- visited = 0
- frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
- frappe.db.set_value("Patient Appointment", appointment.name, "invoiced", False)
- manage_doc_for_appoitnment("Patient Encounter", appointment.name, False)
- elif method == "on_submit" and int(fee_validity.max_visit) > visit:
- if ref_invoice == fee_validity.ref_invoice:
- visited = visited + 1
- frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
- frappe.db.set_value("Patient Appointment", appointment.name, "invoiced", True)
- manage_doc_for_appoitnment("Patient Encounter", appointment.name, True)
- if ref_invoice == fee_validity.ref_invoice:
- visit = visit + 1
-
- if method == "on_cancel":
- ref_invoice_in_fee_validity = frappe.db.get_value("Fee Validity", fee_validity.name, 'ref_invoice')
- if ref_invoice_in_fee_validity == ref_invoice:
- frappe.delete_doc("Fee Validity", fee_validity.name)
-
-def appointments_valid_in_fee_validity(appointment, invoiced):
- valid_days = frappe.db.get_value("Healthcare Settings", None, "valid_days")
- max_visit = frappe.db.get_value("Healthcare Settings", None, "max_visit")
- if int(max_visit) < 1:
- max_visit = 1
- valid_days_date = add_days(getdate(appointment.appointment_date), int(valid_days))
- return frappe.get_list("Patient Appointment",{'patient': appointment.patient, 'invoiced': invoiced,
- 'appointment_date':("<=", valid_days_date), 'appointment_date':(">=", getdate(appointment.appointment_date)),
- 'practitioner': appointment.practitioner}, order_by="appointment_date", limit=int(max_visit)-1)
-
-def manage_doc_for_appoitnment(dt_from_appointment, appointment, invoiced):
- dn_from_appointment = frappe.db.exists(
+def manage_doc_for_appointment(dt_from_appointment, appointment, invoiced):
+ dn_from_appointment = frappe.db.get_value(
dt_from_appointment,
- {
- "appointment": appointment
- }
+ filters={'appointment': appointment}
)
if dn_from_appointment:
- frappe.db.set_value(dt_from_appointment, dn_from_appointment, "invoiced", invoiced)
+ frappe.db.set_value(dt_from_appointment, dn_from_appointment, 'invoiced', invoiced)
+
@frappe.whitelist()
def get_drugs_to_invoice(encounter):
- encounter = frappe.get_doc("Patient Encounter", encounter)
+ encounter = frappe.get_doc('Patient Encounter', encounter)
if encounter:
- patient = frappe.get_doc("Patient", encounter.patient)
- if patient and patient.customer:
- item_to_invoice = []
+ patient = frappe.get_doc('Patient', encounter.patient)
+ if patient:
+ if patient.customer:
+ items_to_invoice = []
for drug_line in encounter.drug_prescription:
if drug_line.drug_code:
qty = 1
- if frappe.db.get_value("Item", drug_line.drug_code, "stock_uom") == "Nos":
+ if frappe.db.get_value('Item', drug_line.drug_code, 'stock_uom') == 'Nos':
qty = drug_line.get_quantity()
- description = False
- if drug_line.dosage:
- description = drug_line.dosage
- if description and drug_line.period:
- description += " for "+drug_line.period
- if not description:
- description = ""
- item_to_invoice.append({'drug_code': drug_line.drug_code, 'quantity': qty,
- 'description': description})
- return item_to_invoice
+
+ description = ''
+ if drug_line.dosage and drug_line.period:
+ description = _('{0} for {1}').format(drug_line.dosage, drug_line.period)
+
+ items_to_invoice.append({
+ 'drug_code': drug_line.drug_code,
+ 'quantity': qty,
+ 'description': description
+ })
+ return items_to_invoice
+ else:
+ validate_customer_created(patient)
+
@frappe.whitelist()
def get_children(doctype, parent, company, is_root=False):
- parent_fieldname = 'parent_' + doctype.lower().replace(' ', '_')
+ parent_fieldname = "parent_" + doctype.lower().replace(" ", "_")
fields = [
- 'name as value',
- 'is_group as expandable',
- 'lft',
- 'rgt'
+ "name as value",
+ "is_group as expandable",
+ "lft",
+ "rgt"
]
- # fields = [ 'name', 'is_group', 'lft', 'rgt' ]
- filters = [['ifnull(`{0}`,"")'.format(parent_fieldname), '=', '' if is_root else parent]]
+ # fields = [ "name", "is_group", "lft", "rgt" ]
+ filters = [["ifnull(`{0}`,'')".format(parent_fieldname), "=", "" if is_root else parent]]
if is_root:
- fields += ['service_unit_type'] if doctype == 'Healthcare Service Unit' else []
- filters.append(['company', '=', company])
+ fields += ["service_unit_type"] if doctype == "Healthcare Service Unit" else []
+ filters.append(["company", "=", company])
else:
- fields += ['service_unit_type', 'allow_appointments', 'inpatient_occupancy', 'occupancy_status'] if doctype == 'Healthcare Service Unit' else []
- fields += [parent_fieldname + ' as parent']
+ fields += ["service_unit_type", "allow_appointments", "inpatient_occupancy", "occupancy_status"] if doctype == "Healthcare Service Unit" else []
+ fields += [parent_fieldname + " as parent"]
hc_service_units = frappe.get_list(doctype, fields=fields, filters=filters)
- if doctype == 'Healthcare Service Unit':
+ if doctype == "Healthcare Service Unit":
for each in hc_service_units:
occupancy_msg = ""
- if each['expandable'] == 1:
+ if each["expandable"] == 1:
occupied = False
vacant = False
- child_list = frappe.db.sql("""
- select name, occupancy_status from `tabHealthcare Service Unit`
- where inpatient_occupancy = 1 and
- lft > %s and rgt < %s""",
- (each['lft'], each['rgt']))
+ child_list = frappe.db.sql(
+ '''
+ SELECT
+ name, occupancy_status
+ FROM
+ `tabHealthcare Service Unit`
+ WHERE
+ inpatient_occupancy = 1
+ and lft > %s and rgt < %s
+ ''', (each['lft'], each['rgt']))
+
for child in child_list:
if not occupied:
occupied = 0
@@ -425,39 +479,44 @@
if child[1] == "Vacant":
vacant += 1
if vacant and occupied:
- occupancy_total = vacant+occupied
+ occupancy_total = vacant + occupied
occupancy_msg = str(occupied) + " Occupied out of " + str(occupancy_total)
each["occupied_out_of_vacant"] = occupancy_msg
return hc_service_units
+
@frappe.whitelist()
def get_patient_vitals(patient, from_date=None, to_date=None):
if not patient: return
- vitals = frappe.db.sql("""select * from `tabVital Signs` where \
- docstatus=1 and patient=%s order by signs_date, signs_time""", \
- (patient), as_dict=1)
- if vitals and vitals[0]:
+
+ vitals = frappe.db.get_all('Vital Signs', {
+ 'docstatus': 1,
+ 'patient': patient
+ }, order_by='signs_date, signs_time')
+
+ if len(vitals):
return vitals
- else:
- return False
+ return False
+
@frappe.whitelist()
def render_docs_as_html(docs):
# docs key value pair {doctype: docname}
docs_html = "<div class='col-md-12 col-sm-12 text-muted'>"
for doc in docs:
- docs_html += render_doc_as_html(doc['doctype'], doc['docname'])['html'] + "<br/>"
+ docs_html += render_doc_as_html(doc['doctype'], doc['docname'])['html'] + '<br/>'
return {'html': docs_html}
+
@frappe.whitelist()
def render_doc_as_html(doctype, docname, exclude_fields = []):
#render document as html, three column layout will break
doc = frappe.get_doc(doctype, docname)
meta = frappe.get_meta(doctype)
doc_html = "<div class='col-md-12 col-sm-12'>"
- section_html = ""
- section_label = ""
- html = ""
+ section_html = ''
+ section_label = ''
+ html = ''
sec_on = False
col_on = 0
has_data = False
@@ -476,8 +535,8 @@
sec_on = True
has_data= False
col_on = 0
- section_html = ""
- html = ""
+ section_html = ''
+ html = ''
if df.label:
section_label = df.label
continue
@@ -493,19 +552,19 @@
d-6 col-sm-6'>" + html + "</div><div class='col-md-6 col-sm-6'>"
elif sec_on and not col_on:
section_html += "<div class='col-md-6 col-sm-6'>"
- html = ""
+ html = ''
col_on += 1
if df.label:
html += '<br>' + df.label
continue
#on table iterate in items and create table based on in_list_view, append to section html or doc html
- if df.fieldtype == "Table":
+ if df.fieldtype == 'Table':
items = doc.get(df.fieldname)
if not items: continue
child_meta = frappe.get_meta(df.options)
if not has_data : has_data = True
- table_head = ""
- table_row = ""
+ table_head = ''
+ table_row = ''
create_head = True
for item in items:
table_row += '<tr>'
@@ -521,24 +580,24 @@
create_head = False
table_row += '</tr>'
if sec_on:
- section_html += '<table class="table table-condensed \
- bordered">' + table_head + table_row + '</table>'
+ section_html += "<table class='table table-condensed \
+ bordered'>" + table_head + table_row + '</table>'
else:
- html += '<table class="table table-condensed table-bordered">' \
- + table_head + table_row + '</table>'
+ html += "<table class='table table-condensed table-bordered'>" \
+ + table_head + table_row + "</table>"
continue
#on other field types add label and value to html
if not df.hidden and not df.print_hide and doc.get(df.fieldname) and df.fieldname not in exclude_fields:
- html += "<br>{0} : {1}".format(df.label or df.fieldname, \
+ html += '<br>{0} : {1}'.format(df.label or df.fieldname, \
doc.get(df.fieldname))
if not has_data : has_data = True
if sec_on and col_on and has_data:
- doc_html += section_html + html + "</div></div>"
+ doc_html += section_html + html + '</div></div>'
elif sec_on and not col_on and has_data:
doc_html += "<div class='col-md-12 col-sm-12'\
><div class='col-md-12 col-sm-12'>" \
- + section_html + html +"</div></div>"
+ + section_html + html +'</div></div>'
if doc_html:
- doc_html = "<div class='small'><div class='col-md-12 text-right'><a class='btn btn-default btn-xs' href='#Form/%s/%s'></a></div>" %(doctype, docname) + doc_html + "</div>"
+ doc_html = "<div class='small'><div class='col-md-12 text-right'><a class='btn btn-default btn-xs' href='#Form/%s/%s'></a></div>" %(doctype, docname) + doc_html + '</div>'
return {'html': doc_html}
diff --git a/erpnext/healthcare/page/appointment_analytic/__init__.py b/erpnext/healthcare/web_form/patient_registration/__init__.py
similarity index 100%
copy from erpnext/healthcare/page/appointment_analytic/__init__.py
copy to erpnext/healthcare/web_form/patient_registration/__init__.py
diff --git a/erpnext/healthcare/web_form/patient_registration/patient_registration.js b/erpnext/healthcare/web_form/patient_registration/patient_registration.js
new file mode 100644
index 0000000..7da3f1f
--- /dev/null
+++ b/erpnext/healthcare/web_form/patient_registration/patient_registration.js
@@ -0,0 +1,3 @@
+frappe.ready(function() {
+ // bind events here
+});
\ No newline at end of file
diff --git a/erpnext/healthcare/web_form/patient_registration/patient_registration.json b/erpnext/healthcare/web_form/patient_registration/patient_registration.json
new file mode 100644
index 0000000..9ed92de
--- /dev/null
+++ b/erpnext/healthcare/web_form/patient_registration/patient_registration.json
@@ -0,0 +1,397 @@
+{
+ "accept_payment": 0,
+ "allow_comments": 0,
+ "allow_delete": 0,
+ "allow_edit": 1,
+ "allow_incomplete": 0,
+ "allow_multiple": 0,
+ "allow_print": 0,
+ "amount": 0.0,
+ "amount_based_on_field": 0,
+ "button_label": "Register",
+ "creation": "2020-03-03 01:01:16.250607",
+ "currency": "INR",
+ "doc_type": "Patient",
+ "docstatus": 0,
+ "doctype": "Web Form",
+ "idx": 0,
+ "introduction_text": "",
+ "is_standard": 1,
+ "login_required": 0,
+ "max_attachment_size": 0,
+ "modified": "2020-03-26 17:25:15.361918",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "patient-registration",
+ "owner": "Administrator",
+ "payment_button_label": "Buy Now",
+ "published": 1,
+ "route": "patient-registration",
+ "route_to_success_link": 0,
+ "show_attachments": 0,
+ "show_in_grid": 0,
+ "show_sidebar": 1,
+ "sidebar_items": [],
+ "success_message": "Registration Successfully. Thank You!",
+ "success_url": "/patient-registration",
+ "title": "Patient Registration",
+ "web_form_fields": [
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "basic_info",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "label": "Patient Demographics",
+ "max_length": 0,
+ "max_value": 0,
+ "options": "fa fa-user",
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "first_name",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "label": "First Name",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 1,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "middle_name",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "label": "Middle Name (optional)",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "last_name",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "label": "Last Name",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 1,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "sex",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "label": "Gender",
+ "max_length": 0,
+ "max_value": 0,
+ "options": "Gender",
+ "read_only": 0,
+ "reqd": 1,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "blood_group",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "label": "Blood Group",
+ "max_length": 0,
+ "max_value": 0,
+ "options": "\nA Positive\nA Negative\nAB Positive\nAB Negative\nB Positive\nB Negative\nO Positive\nO Negative",
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "dob",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "label": "Date of birth",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "mobile",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "label": "Mobile",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "email",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "label": "Email",
+ "max_length": 0,
+ "max_value": 0,
+ "options": "Email",
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "phone",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "label": "Phone",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "label": "Personal Details",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "occupation",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "label": "Occupation",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "marital_status",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "label": "Marital Status",
+ "max_length": 0,
+ "max_value": 0,
+ "options": "\nSingle\nMarried\nDivorced\nWidow",
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "allergy_medical_and_surgical_history",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "label": "Allergies, Medical and Surgical History",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "allergies",
+ "fieldtype": "Small Text",
+ "hidden": 0,
+ "label": "Allergies",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "medication",
+ "fieldtype": "Small Text",
+ "hidden": 0,
+ "label": "Medication",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "column_break_20",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "medical_history",
+ "fieldtype": "Small Text",
+ "hidden": 0,
+ "label": "Medical History",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "surgical_history",
+ "fieldtype": "Small Text",
+ "hidden": 0,
+ "label": "Surgical History",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "risk_factors",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "label": "Risk Factors",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "default": "0",
+ "fieldname": "tobacco_past_use",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "label": "Check if you have a history of Tobacco Consumption",
+ "max_length": 0,
+ "max_value": 0,
+ "options": "",
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "default": "0",
+ "fieldname": "tobacco_current_use",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "label": "Check if you consume Tobacco",
+ "max_length": 0,
+ "max_value": 0,
+ "options": "",
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "default": "0",
+ "fieldname": "alcohol_past_use",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "label": "Check if you have a history of Alcohol Consumption",
+ "max_length": 0,
+ "max_value": 0,
+ "options": "",
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "default": "0",
+ "fieldname": "alcohol_current_use",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "label": "Check if you consume Alcohol",
+ "max_length": 0,
+ "max_value": 0,
+ "options": "",
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "column_break_32",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "surrounding_factors",
+ "fieldtype": "Small Text",
+ "hidden": 0,
+ "label": "Occupational Hazards and Environmental Factors",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ },
+ {
+ "allow_read_on_all_link_options": 0,
+ "fieldname": "other_risk_factors",
+ "fieldtype": "Small Text",
+ "hidden": 0,
+ "label": "Other Risk Factors",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 0,
+ "show_in_filter": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/web_form/patient_registration/patient_registration.py b/erpnext/healthcare/web_form/patient_registration/patient_registration.py
new file mode 100644
index 0000000..1bc4d18
--- /dev/null
+++ b/erpnext/healthcare/web_form/patient_registration/patient_registration.py
@@ -0,0 +1,5 @@
+from __future__ import unicode_literals
+
+def get_context(context):
+ # do your magic here
+ pass
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index b2dc961..2f07e15 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -239,7 +239,7 @@
"on_trash": "erpnext.regional.check_deletion_permission"
},
"Payment Entry": {
- "on_submit": ["erpnext.regional.create_transaction_log", "erpnext.accounts.doctype.payment_request.payment_request.make_status_as_paid"],
+ "on_submit": ["erpnext.regional.create_transaction_log", "erpnext.accounts.doctype.payment_request.payment_request.update_payment_req_status"],
"on_trash": "erpnext.regional.check_deletion_permission"
},
'Address': {
@@ -269,7 +269,8 @@
scheduler_events = {
"all": [
- "erpnext.projects.doctype.project.project.project_status_update_reminder"
+ "erpnext.projects.doctype.project.project.project_status_update_reminder",
+ "erpnext.healthcare_healthcare.doctype.patient_appointment.patient_appointment.send_appointment_reminder"
],
"hourly": [
'erpnext.hr.doctype.daily_work_summary_group.daily_work_summary_group.trigger_emails',
@@ -304,21 +305,22 @@
"erpnext.support.doctype.service_level_agreement.service_level_agreement.check_agreement_status",
"erpnext.crm.doctype.email_campaign.email_campaign.send_email_to_leads_or_contacts",
"erpnext.crm.doctype.email_campaign.email_campaign.set_email_campaign_status",
- "erpnext.selling.doctype.quotation.quotation.set_expired_status"
+ "erpnext.selling.doctype.quotation.quotation.set_expired_status",
+ "erpnext.healthcare.doctype.patient_appointment.patient_appointment.update_appointment_status"
],
"daily_long": [
"erpnext.setup.doctype.email_digest.email_digest.send",
"erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.update_latest_price_in_all_boms",
"erpnext.hr.doctype.leave_ledger_entry.leave_ledger_entry.process_expired_allocation",
"erpnext.hr.utils.generate_leave_encashment",
- "erpnext.loan_management.doctype.loan_security_shortfall.loan_security_shortfall.check_for_ltv_shortfall",
- "erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual.make_accrual_interest_entry_for_term_loans"
+ "erpnext.loan_management.doctype.loan_security_shortfall.loan_security_shortfall.create_process_loan_security_shortfall",
+ "erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual.process_loan_interest_accrual_for_term_loans"
],
"monthly_long": [
"erpnext.accounts.deferred_revenue.convert_deferred_revenue_to_income",
"erpnext.accounts.deferred_revenue.convert_deferred_expense_to_expense",
"erpnext.hr.utils.allocate_earned_leaves",
- "erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual.process_loan_interest_accrual"
+ "erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual.process_loan_interest_accrual_for_demand_loans"
]
}
diff --git a/erpnext/hr/desk_page/hr/hr.json b/erpnext/hr/desk_page/hr/hr.json
index ec38ef0..743aa23 100644
--- a/erpnext/hr/desk_page/hr/hr.json
+++ b/erpnext/hr/desk_page/hr/hr.json
@@ -1,66 +1,79 @@
{
"cards": [
{
- "links": "[\n {\n \"label\": \"Employee\",\n \"name\": \"Employee\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Employment Type\",\n \"name\": \"Employment Type\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Branch\",\n \"name\": \"Branch\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Department\",\n \"name\": \"Department\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Designation\",\n \"name\": \"Designation\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Employee Grade\",\n \"name\": \"Employee Grade\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Group\",\n \"name\": \"Employee Group\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Employee Health Insurance\",\n \"name\": \"Employee Health Insurance\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Employee"
+ "hidden": 0,
+ "label": "Employee",
+ "links": "[\n {\n \"label\": \"Employee\",\n \"name\": \"Employee\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Employment Type\",\n \"name\": \"Employment Type\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Branch\",\n \"name\": \"Branch\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Department\",\n \"name\": \"Department\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Designation\",\n \"name\": \"Designation\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Employee Grade\",\n \"name\": \"Employee Grade\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Group\",\n \"name\": \"Employee Group\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Employee Health Insurance\",\n \"name\": \"Employee Health Insurance\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"dependencies\": [\n \"Job Applicant\"\n ],\n \"label\": \"Employee Onboarding\",\n \"name\": \"Employee Onboarding\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Skill Map\",\n \"name\": \"Employee Skill Map\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Promotion\",\n \"name\": \"Employee Promotion\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Transfer\",\n \"name\": \"Employee Transfer\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Separation\",\n \"name\": \"Employee Separation\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Onboarding Template\",\n \"name\": \"Employee Onboarding Template\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Separation Template\",\n \"name\": \"Employee Separation Template\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Employee Lifecycle"
+ "hidden": 0,
+ "label": "Employee Lifecycle",
+ "links": "[\n {\n \"dependencies\": [\n \"Job Applicant\"\n ],\n \"label\": \"Employee Onboarding\",\n \"name\": \"Employee Onboarding\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Skill Map\",\n \"name\": \"Employee Skill Map\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Promotion\",\n \"name\": \"Employee Promotion\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Transfer\",\n \"name\": \"Employee Transfer\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Separation\",\n \"name\": \"Employee Separation\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Onboarding Template\",\n \"name\": \"Employee Onboarding Template\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Separation Template\",\n \"name\": \"Employee Separation Template\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Shift Type\",\n \"name\": \"Shift Type\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Shift Request\",\n \"name\": \"Shift Request\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Shift Assignment\",\n \"name\": \"Shift Assignment\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Shift Management"
+ "hidden": 0,
+ "label": "Shift Management",
+ "links": "[\n {\n \"label\": \"Shift Type\",\n \"name\": \"Shift Type\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Shift Request\",\n \"name\": \"Shift Request\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Shift Assignment\",\n \"name\": \"Shift Assignment\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Leave Application\",\n \"name\": \"Leave Application\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Leave Allocation\",\n \"name\": \"Leave Allocation\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Leave Type\"\n ],\n \"label\": \"Leave Policy\",\n \"name\": \"Leave Policy\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Leave Period\",\n \"name\": \"Leave Period\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Leave Type\",\n \"name\": \"Leave Type\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Holiday List\",\n \"name\": \"Holiday List\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Compensatory Leave Request\",\n \"name\": \"Compensatory Leave Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Leave Encashment\",\n \"name\": \"Leave Encashment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Leave Block List\",\n \"name\": \"Leave Block List\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Leave Application\"\n ],\n \"doctype\": \"Leave Application\",\n \"is_query_report\": true,\n \"label\": \"Employee Leave Balance\",\n \"name\": \"Employee Leave Balance\",\n \"type\": \"report\"\n }\n]",
- "title": "Leaves"
+ "hidden": 0,
+ "label": "Leaves",
+ "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Leave Application\",\n \"name\": \"Leave Application\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Leave Allocation\",\n \"name\": \"Leave Allocation\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Leave Type\"\n ],\n \"label\": \"Leave Policy\",\n \"name\": \"Leave Policy\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Leave Period\",\n \"name\": \"Leave Period\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Leave Type\",\n \"name\": \"Leave Type\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Holiday List\",\n \"name\": \"Holiday List\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Compensatory Leave Request\",\n \"name\": \"Compensatory Leave Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Leave Encashment\",\n \"name\": \"Leave Encashment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Leave Block List\",\n \"name\": \"Leave Block List\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Leave Application\"\n ],\n \"doctype\": \"Leave Application\",\n \"is_query_report\": true,\n \"label\": \"Employee Leave Balance\",\n \"name\": \"Employee Leave Balance\",\n \"type\": \"report\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Salary Structure\",\n \"name\": \"Salary Structure\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Salary Structure\",\n \"Employee\"\n ],\n \"label\": \"Salary Structure Assignment\",\n \"name\": \"Salary Structure Assignment\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Payroll Entry\",\n \"name\": \"Payroll Entry\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Salary Slip\",\n \"name\": \"Salary Slip\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Payroll Period\",\n \"name\": \"Payroll Period\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Salary Component\",\n \"name\": \"Salary Component\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Additional Salary\",\n \"name\": \"Additional Salary\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Retention Bonus\",\n \"name\": \"Retention Bonus\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Incentive\",\n \"name\": \"Employee Incentive\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Salary Slip\"\n ],\n \"doctype\": \"Salary Slip\",\n \"is_query_report\": true,\n \"label\": \"Salary Register\",\n \"name\": \"Salary Register\",\n \"type\": \"report\"\n }\n]",
- "title": "Payroll"
+ "hidden": 0,
+ "label": "Payroll",
+ "links": "[\n {\n \"label\": \"Salary Structure\",\n \"name\": \"Salary Structure\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Salary Structure\",\n \"Employee\"\n ],\n \"label\": \"Salary Structure Assignment\",\n \"name\": \"Salary Structure Assignment\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Payroll Entry\",\n \"name\": \"Payroll Entry\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Salary Slip\",\n \"name\": \"Salary Slip\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Payroll Period\",\n \"name\": \"Payroll Period\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Salary Component\",\n \"name\": \"Salary Component\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Additional Salary\",\n \"name\": \"Additional Salary\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Retention Bonus\",\n \"name\": \"Retention Bonus\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Incentive\",\n \"name\": \"Employee Incentive\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Salary Slip\"\n ],\n \"doctype\": \"Salary Slip\",\n \"is_query_report\": true,\n \"label\": \"Salary Register\",\n \"name\": \"Salary Register\",\n \"type\": \"report\"\n }\n]"
},
{
- "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"hide_count\": true,\n \"label\": \"Employee Attendance Tool\",\n \"name\": \"Employee Attendance Tool\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Attendance\",\n \"name\": \"Attendance\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Attendance Request\",\n \"name\": \"Attendance Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"hide_count\": true,\n \"label\": \"Upload Attendance\",\n \"name\": \"Upload Attendance\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"hide_count\": true,\n \"label\": \"Employee Checkin\",\n \"name\": \"Employee Checkin\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Attendance\"\n ],\n \"doctype\": \"Attendance\",\n \"is_query_report\": true,\n \"label\": \"Monthly Attendance Sheet\",\n \"name\": \"Monthly Attendance Sheet\",\n \"type\": \"report\"\n }\n]",
- "title": "Attendance"
+ "hidden": 0,
+ "label": "Attendance",
+ "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"hide_count\": true,\n \"label\": \"Employee Attendance Tool\",\n \"name\": \"Employee Attendance Tool\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Attendance\",\n \"name\": \"Attendance\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Attendance Request\",\n \"name\": \"Attendance Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"hide_count\": true,\n \"label\": \"Upload Attendance\",\n \"name\": \"Upload Attendance\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"hide_count\": true,\n \"label\": \"Employee Checkin\",\n \"name\": \"Employee Checkin\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Attendance\"\n ],\n \"doctype\": \"Attendance\",\n \"is_query_report\": true,\n \"label\": \"Monthly Attendance Sheet\",\n \"name\": \"Monthly Attendance Sheet\",\n \"type\": \"report\"\n }\n]"
},
{
- "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Expense Claim\",\n \"name\": \"Expense Claim\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Advance\",\n \"name\": \"Employee Advance\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Expense Claims"
+ "hidden": 0,
+ "label": "Expense Claims",
+ "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Expense Claim\",\n \"name\": \"Expense Claim\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Advance\",\n \"name\": \"Employee Advance\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-cog",
- "links": "[\n {\n \"label\": \"HR Settings\",\n \"name\": \"HR Settings\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Daily Work Summary Group\",\n \"name\": \"Daily Work Summary Group\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Team Updates\",\n \"name\": \"team-updates\",\n \"type\": \"page\"\n }\n]",
- "title": "Settings"
+ "hidden": 0,
+ "label": "Settings",
+ "links": "[\n {\n \"label\": \"HR Settings\",\n \"name\": \"HR Settings\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Daily Work Summary Group\",\n \"name\": \"Daily Work Summary Group\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Team Updates\",\n \"name\": \"team-updates\",\n \"type\": \"page\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Vehicle\",\n \"name\": \"Vehicle\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Vehicle Log\",\n \"name\": \"Vehicle Log\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Vehicle\"\n ],\n \"doctype\": \"Vehicle\",\n \"is_query_report\": true,\n \"label\": \"Vehicle Expenses\",\n \"name\": \"Vehicle Expenses\",\n \"type\": \"report\"\n }\n]",
- "title": "Fleet Management"
+ "hidden": 0,
+ "label": "Fleet Management",
+ "links": "[\n {\n \"label\": \"Vehicle\",\n \"name\": \"Vehicle\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Vehicle Log\",\n \"name\": \"Vehicle Log\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Vehicle\"\n ],\n \"doctype\": \"Vehicle\",\n \"is_query_report\": true,\n \"label\": \"Vehicle Expenses\",\n \"name\": \"Vehicle Expenses\",\n \"type\": \"report\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Job Opening\",\n \"name\": \"Job Opening\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Job Applicant\",\n \"name\": \"Job Applicant\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Job Offer\",\n \"name\": \"Job Offer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Staffing Plan\",\n \"name\": \"Staffing Plan\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Recruitment"
+ "hidden": 0,
+ "label": "Recruitment",
+ "links": "[\n {\n \"label\": \"Job Opening\",\n \"name\": \"Job Opening\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Job Applicant\",\n \"name\": \"Job Applicant\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Job Offer\",\n \"name\": \"Job Offer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Staffing Plan\",\n \"name\": \"Staffing Plan\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Loan Application\",\n \"name\": \"Loan Application\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan\",\n \"name\": \"Loan\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Type\",\n \"name\": \"Loan Type\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Loans"
+ "hidden": 0,
+ "label": "Loans",
+ "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Loan Application\",\n \"name\": \"Loan Application\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan\",\n \"name\": \"Loan\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Type\",\n \"name\": \"Loan Type\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Training Program\",\n \"name\": \"Training Program\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Training Event\",\n \"name\": \"Training Event\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Training Result\",\n \"name\": \"Training Result\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Training Feedback\",\n \"name\": \"Training Feedback\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Training"
+ "hidden": 0,
+ "label": "Training",
+ "links": "[\n {\n \"label\": \"Training Program\",\n \"name\": \"Training Program\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Training Event\",\n \"name\": \"Training Event\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Training Result\",\n \"name\": \"Training Result\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Training Feedback\",\n \"name\": \"Training Feedback\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-list",
- "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"doctype\": \"Employee\",\n \"is_query_report\": true,\n \"label\": \"Employee Birthday\",\n \"name\": \"Employee Birthday\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"doctype\": \"Employee\",\n \"is_query_report\": true,\n \"label\": \"Employees working on a holiday\",\n \"name\": \"Employees working on a holiday\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"doctype\": \"Employee\",\n \"is_query_report\": true,\n \"label\": \"Department Analytics\",\n \"name\": \"Department Analytics\",\n \"type\": \"report\"\n }\n]",
- "title": "Reports"
+ "hidden": 0,
+ "label": "Reports",
+ "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"doctype\": \"Employee\",\n \"is_query_report\": true,\n \"label\": \"Employee Birthday\",\n \"name\": \"Employee Birthday\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"doctype\": \"Employee\",\n \"is_query_report\": true,\n \"label\": \"Employees working on a holiday\",\n \"name\": \"Employees working on a holiday\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"doctype\": \"Employee\",\n \"is_query_report\": true,\n \"label\": \"Department Analytics\",\n \"name\": \"Department Analytics\",\n \"type\": \"report\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Appraisal\",\n \"name\": \"Appraisal\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Appraisal Template\",\n \"name\": \"Appraisal Template\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Energy Point Rule\",\n \"name\": \"Energy Point Rule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Energy Point Log\",\n \"name\": \"Energy Point Log\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Performance"
+ "hidden": 0,
+ "label": "Performance",
+ "links": "[\n {\n \"label\": \"Appraisal\",\n \"name\": \"Appraisal\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Appraisal Template\",\n \"name\": \"Appraisal Template\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Energy Point Rule\",\n \"name\": \"Energy Point Rule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Energy Point Log\",\n \"name\": \"Energy Point Log\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Declaration\",\n \"name\": \"Employee Tax Exemption Declaration\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Proof Submission\",\n \"name\": \"Employee Tax Exemption Proof Submission\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Benefit Application\",\n \"name\": \"Employee Benefit Application\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Benefit Claim\",\n \"name\": \"Employee Benefit Claim\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Category\",\n \"name\": \"Employee Tax Exemption Category\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Sub Category\",\n \"name\": \"Employee Tax Exemption Sub Category\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Employee Tax and Benefits"
+ "hidden": 0,
+ "label": "Employee Tax and Benefits",
+ "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Declaration\",\n \"name\": \"Employee Tax Exemption Declaration\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Proof Submission\",\n \"name\": \"Employee Tax Exemption Proof Submission\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Benefit Application\",\n \"name\": \"Employee Benefit Application\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Benefit Claim\",\n \"name\": \"Employee Benefit Claim\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Category\",\n \"name\": \"Employee Tax Exemption Category\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Sub Category\",\n \"name\": \"Employee Tax Exemption Sub Category\",\n \"type\": \"doctype\"\n }\n]"
}
],
"category": "Modules",
@@ -75,7 +88,7 @@
"idx": 0,
"is_standard": 1,
"label": "HR",
- "modified": "2020-03-12 16:30:35.211246",
+ "modified": "2020-04-01 11:28:50.860012",
"modified_by": "Administrator",
"module": "HR",
"name": "HR",
@@ -85,37 +98,37 @@
"shortcuts": [
{
"format": "{} Active",
- "is_query_report": 0,
+ "label": "Employee",
"link_to": "Employee",
"stats_filter": "{\"status\":\"Active\"}",
"type": "DocType"
},
{
"format": "{} Unpaid",
- "is_query_report": 0,
+ "label": "Expense Claim",
"link_to": "Expense Claim",
"stats_filter": "{\"approval_status\":\"Draft\"}",
"type": "DocType"
},
{
"format": "{} Open",
- "is_query_report": 0,
+ "label": "Job Applicant",
"link_to": "Job Applicant",
"stats_filter": "{\n \"status\": \"Open\"\n}",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Salary Structure",
"link_to": "Salary Structure",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Leave Application",
"link_to": "Leave Application",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Salary Register",
"link_to": "Salary Register",
"type": "Report"
}
diff --git a/erpnext/hr/doctype/employee/employee.js b/erpnext/hr/doctype/employee/employee.js
index 7d153d4..c21d4b8 100755
--- a/erpnext/hr/doctype/employee/employee.js
+++ b/erpnext/hr/doctype/employee/employee.js
@@ -55,8 +55,8 @@
};
});
},
- prefered_contact_email:function(frm){
- frm.events.update_contact(frm)
+ prefered_contact_email:function(frm){
+ frm.events.update_contact(frm)
},
personal_email:function(frm){
frm.events.update_contact(frm)
diff --git a/erpnext/hr/doctype/employee/employee.json b/erpnext/hr/doctype/employee/employee.json
index 3f0b9c4..13c202c 100644
--- a/erpnext/hr/doctype/employee/employee.json
+++ b/erpnext/hr/doctype/employee/employee.json
@@ -259,7 +259,8 @@
"bold": 1,
"fieldname": "emergency_phone_number",
"fieldtype": "Data",
- "label": "Emergency Phone"
+ "label": "Emergency Phone",
+ "options": "Phone"
},
{
"bold": 1,
@@ -480,7 +481,8 @@
{
"fieldname": "cell_number",
"fieldtype": "Data",
- "label": "Mobile"
+ "label": "Mobile",
+ "options": "Phone"
},
{
"fieldname": "prefered_contact_email",
@@ -787,7 +789,7 @@
"idx": 24,
"image_field": "image",
"links": [],
- "modified": "2020-01-09 04:23:55.611366",
+ "modified": "2020-04-08 12:25:34.306695",
"modified_by": "Administrator",
"module": "HR",
"name": "Employee",
@@ -834,6 +836,5 @@
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
- "title_field": "employee_name",
- "track_changes": 1
-}
+ "title_field": "employee_name"
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py
index f78e17f..c441751 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.py
+++ b/erpnext/hr/doctype/leave_application/leave_application.py
@@ -580,19 +580,22 @@
return leave_days
def skip_expiry_leaves(leave_entry, date):
- ''' Checks whether the expired leaves coincide with the to_date of leave balance check '''
+ ''' Checks whether the expired leaves coincide with the to_date of leave balance check.
+ This allows backdated leave entry creation for non carry forwarded allocation '''
end_date = frappe.db.get_value("Leave Allocation", {'name': leave_entry.transaction_name}, ['to_date'])
return True if end_date == date and not leave_entry.is_carry_forward else False
def get_leave_entries(employee, leave_type, from_date, to_date):
- ''' Returns leave entries between from_date and to_date '''
+ ''' Returns leave entries between from_date and to_date. '''
return frappe.db.sql("""
SELECT
employee, leave_type, from_date, to_date, leaves, transaction_name, transaction_type,
is_carry_forward, is_expired
FROM `tabLeave Ledger Entry`
WHERE employee=%(employee)s AND leave_type=%(leave_type)s
- AND docstatus=1 AND leaves<0
+ AND docstatus=1
+ AND (leaves<0
+ OR is_expired=1)
AND (from_date between %(from_date)s AND %(to_date)s
OR to_date between %(from_date)s AND %(to_date)s
OR (from_date < %(from_date)s AND to_date > %(to_date)s))
@@ -687,8 +690,7 @@
"to_date": d.to_date,
"docstatus": d.docstatus,
"color": d.color,
- "title": cstr(d.employee_name) + \
- (d.half_day and _(" (Half Day)") or ""),
+ "title": cstr(d.employee_name) + (' ' + _('(Half Day)') if d.half_day else ''),
}
if e not in events:
events.append(e)
diff --git a/erpnext/hr/doctype/leave_encashment/leave_encashment.py b/erpnext/hr/doctype/leave_encashment/leave_encashment.py
index ad2cc02..7d6fd42 100644
--- a/erpnext/hr/doctype/leave_encashment/leave_encashment.py
+++ b/erpnext/hr/doctype/leave_encashment/leave_encashment.py
@@ -8,7 +8,6 @@
from frappe.model.document import Document
from frappe.utils import getdate, nowdate, flt
from erpnext.hr.utils import set_employee_name
-from erpnext.hr.doctype.leave_application.leave_application import get_leave_balance_on
from erpnext.hr.doctype.salary_structure_assignment.salary_structure_assignment import get_assigned_salary_structure
from erpnext.hr.doctype.leave_ledger_entry.leave_ledger_entry import create_leave_ledger_entry
from erpnext.hr.doctype.leave_allocation.leave_allocation import get_unused_leaves
diff --git a/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.py b/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.py
index bfc6d95..9ed58c9 100644
--- a/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.py
+++ b/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.py
@@ -141,6 +141,7 @@
leaves = get_remaining_leaves(allocation)
expiry_date = expiry_date if expiry_date else allocation.to_date
+ # allows expired leaves entry to be created/reverted
if leaves:
args = dict(
leaves=flt(leaves) * -1,
@@ -160,6 +161,8 @@
from erpnext.hr.doctype.leave_application.leave_application import get_leaves_for_period
leaves_taken = get_leaves_for_period(allocation.employee, allocation.leave_type, allocation.from_date, allocation.to_date)
leaves = flt(allocation.leaves) + flt(leaves_taken)
+
+ # allow expired leaves entry to be created
if leaves > 0:
args = frappe._dict(
transaction_name=allocation.name,
diff --git a/erpnext/hr/doctype/payroll_entry/test_payroll_entry.py b/erpnext/hr/doctype/payroll_entry/test_payroll_entry.py
index 35f5a57..49671d5 100644
--- a/erpnext/hr/doctype/payroll_entry/test_payroll_entry.py
+++ b/erpnext/hr/doctype/payroll_entry/test_payroll_entry.py
@@ -13,7 +13,7 @@
make_earning_salary_component, make_deduction_salary_component
from erpnext.hr.doctype.salary_structure.test_salary_structure import make_salary_structure
from erpnext.loan_management.doctype.loan.test_loan import create_loan, make_loan_disbursement_entry
-from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import make_accrual_interest_entry_for_term_loans
+from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_term_loans
class TestPayrollEntry(unittest.TestCase):
def setUp(self):
@@ -81,7 +81,7 @@
make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=add_months(nowdate(), -1))
- make_accrual_interest_entry_for_term_loans(posting_date=nowdate())
+ process_loan_interest_accrual_for_term_loans(posting_date=nowdate())
dates = get_start_end_dates('Monthly', nowdate())
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.json b/erpnext/hr/doctype/salary_slip/salary_slip.json
index e73d41a..097d3a0 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.json
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.json
@@ -372,8 +372,7 @@
"fieldtype": "Table",
"label": "Employee Loan",
"options": "Salary Slip Loan",
- "print_hide": 1,
- "read_only": 1
+ "print_hide": 1
},
{
"fieldname": "section_break_43",
@@ -464,7 +463,7 @@
"idx": 9,
"is_submittable": 1,
"links": [],
- "modified": "2019-12-31 17:13:45.146271",
+ "modified": "2020-04-09 20:02:53.159827",
"modified_by": "Administrator",
"module": "HR",
"name": "Salary Slip",
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index d03a3dd..b3c803b 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -356,13 +356,13 @@
def eval_condition_and_formula(self, d, data):
try:
- condition = d.condition.strip() if d.condition else None
+ condition = d.condition.strip().replace("\n", " ") if d.condition else None
if condition:
if not frappe.safe_eval(condition, self.whitelisted_globals, data):
return None
amount = d.amount
if d.amount_based_on_formula:
- formula = d.formula.strip() if d.formula else None
+ formula = d.formula.strip().replace("\n", " ") if d.formula else None
if formula:
amount = flt(frappe.safe_eval(formula, self.whitelisted_globals, data), d.precision("amount"))
if amount:
@@ -755,30 +755,43 @@
d.amount = self.get_amount_based_on_payment_days(d, joining_date, relieving_date)[0]
def set_loan_repayment(self):
- self.set('loans', [])
self.total_loan_repayment = 0
self.total_interest_amount = 0
self.total_principal_amount = 0
- for loan in self.get_loan_details():
+ if not self.get('loans'):
+ for loan in self.get_loan_details():
- amounts = calculate_amounts(loan.name, self.posting_date, "Regular Payment")
+ amounts = calculate_amounts(loan.name, self.posting_date, "Regular Payment")
- total_payment = amounts['interest_amount'] + amounts['payable_principal_amount']
+ if amounts['interest_amount'] or amounts['payable_principal_amount']:
+ self.append('loans', {
+ 'loan': loan.name,
+ 'total_payment': amounts['interest_amount'] + amounts['payable_principal_amount'],
+ 'interest_amount': amounts['interest_amount'],
+ 'principal_amount': amounts['payable_principal_amount'],
+ 'loan_account': loan.loan_account,
+ 'interest_income_account': loan.interest_income_account
+ })
- if total_payment:
- self.append('loans', {
- 'loan': loan.name,
- 'total_payment': total_payment,
- 'interest_amount': amounts['interest_amount'],
- 'principal_amount': amounts['payable_principal_amount'],
- 'loan_account': loan.loan_account,
- 'interest_income_account': loan.interest_income_account
- })
+ for payment in self.get('loans'):
+ amounts = calculate_amounts(payment.loan, self.posting_date, "Regular Payment")
- self.total_loan_repayment += total_payment
- self.total_interest_amount += amounts['interest_amount']
- self.total_principal_amount += amounts['payable_principal_amount']
+ if payment.interest_amount > amounts['interest_amount']:
+ frappe.throw(_("""Row {0}: Paid Interest amount {1} is greater than pending interest amount {2}
+ against loan {3}""").format(payment.idx, frappe.bold(payment.interest_amount),
+ frappe.bold(amounts['interest_amount']), frappe.bold(payment.loan)))
+
+ if payment.principal_amount > amounts['payable_principal_amount']:
+ frappe.throw(_("""Row {0}: Paid Principal amount {1} is greater than pending principal amount {2}
+ against loan {3}""").format(payment.idx, frappe.bold(payment.principal_amount),
+ frappe.bold(amounts['payable_principal_amount']), frappe.bold(payment.loan)))
+
+ payment.total_payment = payment.interest_amount + payment.principal_amount
+ self.total_interest_amount += payment.interest_amount
+ self.total_principal_amount += payment.principal_amount
+
+ self.total_loan_repayment = self.total_interest_amount + self.total_principal_amount
def get_loan_details(self):
diff --git a/erpnext/hr/doctype/salary_slip/test_salary_slip.py b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
index 9acfd1f..ecccac7 100644
--- a/erpnext/hr/doctype/salary_slip/test_salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
@@ -146,7 +146,7 @@
def test_loan_repayment_salary_slip(self):
from erpnext.loan_management.doctype.loan.test_loan import create_loan_type, create_loan, make_loan_disbursement_entry, create_loan_accounts
- from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import make_accrual_interest_entry_for_term_loans
+ from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_term_loans
applicant = make_employee("test_loanemployee@salary.com", company="_Test Company")
@@ -166,7 +166,7 @@
make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=add_months(nowdate(), -1))
- make_accrual_interest_entry_for_term_loans(posting_date=nowdate())
+ process_loan_interest_accrual_for_term_loans(posting_date=nowdate())
ss = make_employee_salary_slip("test_loanemployee@salary.com", "Monthly")
ss.submit()
diff --git a/erpnext/loan_management/desk_page/loan_management/loan_management.json b/erpnext/loan_management/desk_page/loan_management/loan_management.json
index 1d60ca4..691d2c1 100644
--- a/erpnext/loan_management/desk_page/loan_management/loan_management.json
+++ b/erpnext/loan_management/desk_page/loan_management/loan_management.json
@@ -1,24 +1,29 @@
{
"cards": [
{
- "links": "[\n {\n \"description\": \"Loan Type for interest and penalty rates\",\n \"label\": \"Loan Type\",\n \"name\": \"Loan Type\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Loan Applications from customers and employees.\",\n \"label\": \"Loan Application\",\n \"name\": \"Loan Application\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Loans provided to customers and employees.\",\n \"label\": \"Loan\",\n \"name\": \"Loan\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Loan"
+ "hidden": 0,
+ "label": "Loan",
+ "links": "[\n {\n \"description\": \"Loan Type for interest and penalty rates\",\n \"label\": \"Loan Type\",\n \"name\": \"Loan Type\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Loan Applications from customers and employees.\",\n \"label\": \"Loan Application\",\n \"name\": \"Loan Application\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Loans provided to customers and employees.\",\n \"label\": \"Loan\",\n \"name\": \"Loan\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Process Loan Security Shortfall\",\n \"name\": \"Process Loan Security Shortfall\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Process Loan Interest Accrual\",\n \"name\": \"Process Loan Interest Accrual\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Loan Processes"
+ "hidden": 0,
+ "label": "Loan Processes",
+ "links": "[\n {\n \"label\": \"Process Loan Security Shortfall\",\n \"name\": \"Process Loan Security Shortfall\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Process Loan Interest Accrual\",\n \"name\": \"Process Loan Interest Accrual\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Loan Disbursement\",\n \"name\": \"Loan Disbursement\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Repayment\",\n \"name\": \"Loan Repayment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Interest Accrual\",\n \"name\": \"Loan Interest Accrual\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Disbursement and Repayment"
+ "hidden": 0,
+ "label": "Disbursement and Repayment",
+ "links": "[\n {\n \"label\": \"Loan Disbursement\",\n \"name\": \"Loan Disbursement\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Repayment\",\n \"name\": \"Loan Repayment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Interest Accrual\",\n \"name\": \"Loan Interest Accrual\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Loan Security Type\",\n \"name\": \"Loan Security Type\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Security Price\",\n \"name\": \"Loan Security Price\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Security\",\n \"name\": \"Loan Security\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Security Pledge\",\n \"name\": \"Loan Security Pledge\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Security Unpledge\",\n \"name\": \"Loan Security Unpledge\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Security Shortfall\",\n \"name\": \"Loan Security Shortfall\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Loan Security"
+ "hidden": 0,
+ "label": "Loan Security",
+ "links": "[\n {\n \"label\": \"Loan Security Type\",\n \"name\": \"Loan Security Type\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Security Price\",\n \"name\": \"Loan Security Price\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Security\",\n \"name\": \"Loan Security\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Security Pledge\",\n \"name\": \"Loan Security Pledge\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Security Unpledge\",\n \"name\": \"Loan Security Unpledge\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Security Shortfall\",\n \"name\": \"Loan Security Shortfall\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"dependencies\": [\n \"Loan Repayment\"\n ],\n \"doctype\": \"Loan Repayment\",\n \"incomplete_dependencies\": [\n \"Loan Repayment\"\n ],\n \"is_query_report\": true,\n \"label\": \"Loan Repayment and Closure\",\n \"name\": \"Loan Repayment and Closure\",\n \"route\": \"#query-report/Loan Repayment and Closure\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Loan Security Pledge\"\n ],\n \"doctype\": \"Loan Security Pledge\",\n \"incomplete_dependencies\": [\n \"Loan Security Pledge\"\n ],\n \"is_query_report\": true,\n \"label\": \"Loan Security Status\",\n \"name\": \"Loan Security Status\",\n \"route\": \"#query-report/Loan Security Status\",\n \"type\": \"report\"\n }\n]",
- "title": "Reports"
+ "hidden": 0,
+ "label": "Reports",
+ "links": "[\n {\n \"dependencies\": [\n \"Loan Repayment\"\n ],\n \"doctype\": \"Loan Repayment\",\n \"incomplete_dependencies\": [\n \"Loan Repayment\"\n ],\n \"is_query_report\": true,\n \"label\": \"Loan Repayment and Closure\",\n \"name\": \"Loan Repayment and Closure\",\n \"route\": \"#query-report/Loan Repayment and Closure\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Loan Security Pledge\"\n ],\n \"doctype\": \"Loan Security Pledge\",\n \"incomplete_dependencies\": [\n \"Loan Security Pledge\"\n ],\n \"is_query_report\": true,\n \"label\": \"Loan Security Status\",\n \"name\": \"Loan Security Status\",\n \"route\": \"#query-report/Loan Security Status\",\n \"type\": \"report\"\n }\n]"
}
],
"category": "Modules",
@@ -32,7 +37,7 @@
"idx": 0,
"is_standard": 1,
"label": "Loan Management",
- "modified": "2020-03-12 16:38:00.347959",
+ "modified": "2020-04-01 11:28:51.380509",
"modified_by": "Administrator",
"module": "Loan Management",
"name": "Loan Management",
@@ -41,12 +46,12 @@
"pin_to_top": 0,
"shortcuts": [
{
- "is_query_report": 0,
+ "label": "Loan Application",
"link_to": "Loan Application",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Loan",
"link_to": "Loan",
"type": "DocType"
}
diff --git a/erpnext/loan_management/doctype/loan/loan.js b/erpnext/loan_management/doctype/loan/loan.js
index 8b22017..9cd8b2e 100644
--- a/erpnext/loan_management/doctype/loan/loan.js
+++ b/erpnext/loan_management/doctype/loan/loan.js
@@ -97,6 +97,8 @@
"company": frm.doc.company,
"applicant_type": frm.doc.applicant_type,
"applicant": frm.doc.applicant,
+ "pending_amount": frm.doc.loan_amount - frm.doc.disbursed_amount > 0 ?
+ frm.doc.loan_amount - frm.doc.disbursed_amount : 0,
"as_dict": 1
},
method: "erpnext.loan_management.doctype.loan.loan.make_loan_disbursement",
@@ -149,10 +151,10 @@
return frappe.call({
method: "erpnext.loan_management.doctype.loan.loan.get_loan_application",
args: {
- "loan_application": frm.doc.loan_application
- },
- callback: function (r) {
- if (!r.exc && r.message) {
+ "loan_application": frm.doc.loan_application
+ },
+ callback: function (r) {
+ if (!r.exc && r.message) {
let loan_fields = ["loan_type", "loan_amount", "repayment_method",
"monthly_repayment_amount", "repayment_periods", "rate_of_interest", "is_secured_loan"]
diff --git a/erpnext/loan_management/doctype/loan/loan.json b/erpnext/loan_management/doctype/loan/loan.json
index 2834e5b..b04e822 100644
--- a/erpnext/loan_management/doctype/loan/loan.json
+++ b/erpnext/loan_management/doctype/loan/loan.json
@@ -126,7 +126,7 @@
"depends_on": "eval:doc.applicant_type==\"Employee\"",
"fieldname": "repay_from_salary",
"fieldtype": "Check",
- "label": "Repay from Salary"
+ "label": "Repay From Salary"
},
{
"fieldname": "section_break_8",
@@ -178,6 +178,8 @@
},
{
"depends_on": "is_term_loan",
+ "fetch_from": "loan_application.repayment_amount",
+ "fetch_if_empty": 1,
"fieldname": "monthly_repayment_amount",
"fieldtype": "Currency",
"label": "Monthly Repayment Amount",
@@ -350,7 +352,7 @@
],
"is_submittable": 1,
"links": [],
- "modified": "2020-02-07 01:31:25.172173",
+ "modified": "2020-04-13 13:16:10.192624",
"modified_by": "Administrator",
"module": "Loan Management",
"name": "Loan",
diff --git a/erpnext/loan_management/doctype/loan/loan.py b/erpnext/loan_management/doctype/loan/loan.py
index 696410b..c7a2fba 100644
--- a/erpnext/loan_management/doctype/loan/loan.py
+++ b/erpnext/loan_management/doctype/loan/loan.py
@@ -19,6 +19,7 @@
self.validate_loan_security_pledge()
self.validate_loan_amount()
self.check_sanctioned_amount_limit()
+ self.validate_repay_from_salary()
if self.is_term_loan:
validate_repayment_method(self.repayment_method, self.loan_amount, self.monthly_repayment_amount,
@@ -77,6 +78,10 @@
if sanctioned_amount_limit and flt(self.loan_amount) + flt(total_loan_amount) > flt(sanctioned_amount_limit):
frappe.throw(_("Sanctioned Amount limit crossed for {0} {1}").format(self.applicant_type, frappe.bold(self.applicant)))
+ def validate_repay_from_salary(self):
+ if not self.is_term_loan and self.repay_from_salary:
+ frappe.throw(_("Repay From Salary can be selected only for term loans"))
+
def make_repayment_schedule(self):
if not self.repayment_start_date:
@@ -198,7 +203,7 @@
frappe.db.set_value("Loan", loan, "status", "Closed")
@frappe.whitelist()
-def make_loan_disbursement(loan, company, applicant_type, applicant, disbursed_amount=0, as_dict=0):
+def make_loan_disbursement(loan, company, applicant_type, applicant, pending_amount=0, as_dict=0):
disbursement_entry = frappe.new_doc("Loan Disbursement")
disbursement_entry.against_loan = loan
disbursement_entry.applicant_type = applicant_type
@@ -206,8 +211,7 @@
disbursement_entry.company = company
disbursement_entry.disbursement_date = nowdate()
- if disbursed_amount:
- disbursement_entry.disbursed_amount = disbursed_amount
+ disbursement_entry.disbursed_amount = pending_amount
if as_dict:
return disbursement_entry.as_dict()
else:
diff --git a/erpnext/loan_management/doctype/loan/test_loan.py b/erpnext/loan_management/doctype/loan/test_loan.py
index 759b0d8..108672b 100644
--- a/erpnext/loan_management/doctype/loan/test_loan.py
+++ b/erpnext/loan_management/doctype/loan/test_loan.py
@@ -10,10 +10,10 @@
add_months, get_first_day, get_last_day, flt, date_diff)
from erpnext.selling.doctype.customer.test_customer import get_customer_dict
from erpnext.hr.doctype.salary_structure.test_salary_structure import make_employee
-from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual
-from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import (make_accrual_interest_entry_for_term_loans, days_in_year)
-
-from erpnext.loan_management.doctype.loan_security_shortfall.loan_security_shortfall import check_for_ltv_shortfall
+from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import (process_loan_interest_accrual_for_demand_loans,
+ process_loan_interest_accrual_for_term_loans)
+from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import days_in_year
+from erpnext.loan_management.doctype.process_loan_security_shortfall.process_loan_security_shortfall import create_process_loan_security_shortfall
class TestLoan(unittest.TestCase):
def setUp(self):
@@ -145,7 +145,7 @@
make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=first_date)
- process_loan_interest_accrual(posting_date = last_date)
+ process_loan_interest_accrual_for_demand_loans(posting_date = last_date)
repayment_entry = create_repayment_entry(loan.name, self.applicant2, add_days(last_date, 10), "Regular Payment", 111118.68)
repayment_entry.save()
@@ -186,7 +186,7 @@
/ (days_in_year(get_datetime(first_date).year) * 100)
make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=first_date)
- process_loan_interest_accrual(posting_date = last_date)
+ process_loan_interest_accrual_for_demand_loans(posting_date = last_date)
repayment_entry = create_repayment_entry(loan.name, self.applicant2, add_days(last_date, 5),
"Loan Closure", 13315.0681)
@@ -224,7 +224,7 @@
make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=add_months(nowdate(), -1))
- make_accrual_interest_entry_for_term_loans(posting_date=nowdate())
+ process_loan_interest_accrual_for_term_loans(posting_date=nowdate())
repayment_entry = create_repayment_entry(loan.name, self.applicant2, add_days(get_last_day(nowdate()), 5),
"Regular Payment", 89768.7534247)
@@ -264,8 +264,8 @@
make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=first_date)
- process_loan_interest_accrual(posting_date = add_days(first_date, 15))
- process_loan_interest_accrual(posting_date = add_days(first_date, 30))
+ process_loan_interest_accrual_for_demand_loans(posting_date = add_days(first_date, 15))
+ process_loan_interest_accrual_for_demand_loans(posting_date = add_days(first_date, 30))
repayment_entry = create_repayment_entry(loan.name, self.applicant2, add_days(last_date, 1), "Regular Payment", 6500)
repayment_entry.save()
@@ -297,7 +297,7 @@
frappe.db.sql(""" UPDATE `tabLoan Security Price` SET loan_security_price = 100
where loan_security='Test Security 2'""")
- check_for_ltv_shortfall()
+ create_process_loan_security_shortfall()
loan_security_shortfall = frappe.get_doc("Loan Security Shortfall", {"loan": loan.name})
self.assertTrue(loan_security_shortfall)
diff --git a/erpnext/loan_management/doctype/loan_application/loan_application.js b/erpnext/loan_management/doctype/loan_application/loan_application.js
index 57050d8..aba5f42 100644
--- a/erpnext/loan_management/doctype/loan_application/loan_application.js
+++ b/erpnext/loan_management/doctype/loan_application/loan_application.js
@@ -31,13 +31,15 @@
add_toolbar_buttons: function(frm) {
if (frm.doc.status == "Approved") {
- frappe.db.get_value("Loan Security Pledge", {"loan_application": frm.doc.name, "docstatus": 1}, "name", (r) => {
- if (!r) {
- frm.add_custom_button(__('Loan Security Pledge'), function() {
- frm.trigger('create_loan_security_pledge')
- },__('Create'))
- }
- });
+ if (frm.doc.is_secured) {
+ frappe.db.get_value("Loan Security Pledge", {"loan_application": frm.doc.name, "docstatus": 1}, "name", (r) => {
+ if (!r) {
+ frm.add_custom_button(__('Loan Security Pledge'), function() {
+ frm.trigger('create_loan_security_pledge')
+ },__('Create'))
+ }
+ });
+ }
frappe.db.get_value("Loan", {"loan_application": frm.doc.name, "docstatus": 1}, "name", (r) => {
if (!r) {
@@ -61,6 +63,11 @@
});
},
create_loan_security_pledge: function(frm) {
+
+ if(!frm.doc.is_secured_loan) {
+ frappe.throw(__("Loan Security Pledge can only be created for secured loans"));
+ }
+
frappe.call({
method: "erpnext.loan_management.doctype.loan_application.loan_application.create_pledge",
args: {
diff --git a/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.json b/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.json
index 72a4ddc..2d9c45d 100644
--- a/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.json
+++ b/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.json
@@ -1,4 +1,5 @@
{
+ "actions": [],
"autoname": "LM-DIS-.#####",
"creation": "2019-09-07 12:44:49.125452",
"doctype": "DocType",
@@ -13,7 +14,6 @@
"applicant_type",
"applicant",
"section_break_7",
- "pending_amount_for_disbursal",
"disbursed_amount",
"accounting_dimensions_section",
"cost_center",
@@ -84,13 +84,6 @@
"read_only": 1
},
{
- "fieldname": "pending_amount_for_disbursal",
- "fieldtype": "Currency",
- "label": "Pending Amount For Disbursal",
- "options": "Company:company:default_currency",
- "read_only": 1
- },
- {
"fieldname": "column_break_4",
"fieldtype": "Column Break"
},
@@ -99,6 +92,7 @@
"fieldtype": "Section Break"
},
{
+ "collapsible": 1,
"fieldname": "section_break_13",
"fieldtype": "Section Break"
},
@@ -123,7 +117,8 @@
}
],
"is_submittable": 1,
- "modified": "2019-10-24 12:32:32.230881",
+ "links": [],
+ "modified": "2020-04-09 14:44:28.527271",
"modified_by": "Administrator",
"module": "Loan Management",
"name": "Loan Disbursement",
diff --git a/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py b/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py
index fa7db2d..2918486 100644
--- a/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py
+++ b/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py
@@ -4,21 +4,24 @@
from __future__ import unicode_literals
import frappe, erpnext
+from frappe import _
from frappe.model.document import Document
from frappe.utils import nowdate, getdate, add_days, flt
from erpnext.controllers.accounts_controller import AccountsController
from erpnext.accounts.general_ledger import make_gl_entries
-from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual
+from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_demand_loans
class LoanDisbursement(AccountsController):
def validate(self):
self.set_missing_values()
- self.set_pending_amount_for_disbursal()
def before_submit(self):
self.set_status_and_amounts()
+ def before_cancel(self):
+ self.set_status_and_amounts(cancel=1)
+
def on_submit(self):
self.make_gl_entries()
@@ -38,13 +41,7 @@
if not self.bank_account and self.applicant_type == "Customer":
self.bank_account = frappe.db.get_value("Customer", self.applicant, "default_bank_account")
- def set_pending_amount_for_disbursal(self):
- loan_amount, disbursed_amount = frappe.db.get_value('Loan',
- {'name': self.against_loan}, ['loan_amount', 'disbursed_amount'])
-
- self.pending_amount_for_disbursal = loan_amount - disbursed_amount
-
- def set_status_and_amounts(self):
+ def set_status_and_amounts(self, cancel=0):
loan_details = frappe.get_all("Loan",
fields = ["loan_amount", "disbursed_amount", "total_principal_paid", "status", "is_term_loan"],
@@ -52,26 +49,32 @@
)[0]
if loan_details.status == "Disbursed" and not loan_details.is_term_loan:
- process_loan_interest_accrual(posting_date=add_days(self.disbursement_date, -1),
+ process_loan_interest_accrual_for_demand_loans(posting_date=add_days(self.disbursement_date, -1),
loan=self.against_loan)
- disbursed_amount = self.disbursed_amount + loan_details.disbursed_amount
-
- if flt(disbursed_amount) - flt(loan_details.total_principal_paid) > flt(loan_details.loan_amount):
- frappe.throw(_("Disbursed Amount cannot be greater than loan amount"))
-
- if flt(disbursed_amount) > flt(loan_details.loan_amount):
- total_principal_paid = loan_details.total_principal_paid - (disbursed_amount - loan_details.loan_amount)
- frappe.db.set_value("Loan", self.against_loan, "total_principal_paid", total_principal_paid)
-
- if flt(loan_details.loan_amount) == flt(disbursed_amount):
- frappe.db.set_value("Loan", self.against_loan, "status", "Disbursed")
+ if cancel:
+ disbursed_amount = loan_details.disbursed_amount - self.disbursed_amount
+ if disbursed_amount == 0:
+ status = "Sanctioned"
+ elif disbursed_amount >= loan_details.disbursed_amount:
+ status = "Disbursed"
+ else:
+ status = "Partially Disbursed"
else:
- frappe.db.set_value("Loan", self.against_loan, "status", "Partially Disbursed")
+ disbursed_amount = self.disbursed_amount + loan_details.disbursed_amount
+
+ if flt(disbursed_amount) - flt(loan_details.total_principal_paid) > flt(loan_details.loan_amount):
+ frappe.throw(_("Disbursed Amount cannot be greater than loan amount"))
+
+ if flt(disbursed_amount) >= loan_details.disbursed_amount:
+ status = "Disbursed"
+ else:
+ status = "Partially Disbursed"
frappe.db.set_value("Loan", self.against_loan, {
"disbursement_date": self.disbursement_date,
- "disbursed_amount": disbursed_amount
+ "disbursed_amount": disbursed_amount,
+ "status": status
})
def make_gl_entries(self, cancel=0, adv_adj=0):
diff --git a/erpnext/loan_management/doctype/loan_disbursement/test_loan_disbursement.py b/erpnext/loan_management/doctype/loan_disbursement/test_loan_disbursement.py
index 968e377..189b2f5 100644
--- a/erpnext/loan_management/doctype/loan_disbursement/test_loan_disbursement.py
+++ b/erpnext/loan_management/doctype/loan_disbursement/test_loan_disbursement.py
@@ -7,8 +7,8 @@
from frappe.utils import (nowdate, add_days, get_datetime, get_first_day, get_last_day, date_diff, flt, add_to_date)
from erpnext.loan_management.doctype.loan.test_loan import (create_loan_type, create_loan_security_pledge, create_repayment_entry,
make_loan_disbursement_entry, create_loan_accounts, create_loan_security_type, create_loan_security, create_demand_loan, create_loan_security_price)
-from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual
-from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import (make_accrual_interest_entry_for_term_loans, days_in_year)
+from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_demand_loans
+from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import days_in_year
from erpnext.selling.doctype.customer.test_customer import get_customer_dict
class TestLoanDisbursement(unittest.TestCase):
@@ -56,7 +56,7 @@
make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=first_date)
- process_loan_interest_accrual(posting_date=add_days(last_date, 1))
+ process_loan_interest_accrual_for_demand_loans(posting_date=add_days(last_date, 1))
# Paid 511095.89 amount includes 5,00,000 principal amount and 11095.89 interest amount
repayment_entry = create_repayment_entry(loan.name, self.applicant, add_days(get_last_day(nowdate()), 5),
diff --git a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.json b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.json
index 33f496f..a261120 100644
--- a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.json
+++ b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.json
@@ -23,6 +23,7 @@
"interest_amount",
"section_break_15",
"process_loan_interest_accrual",
+ "repayment_schedule_name",
"amended_from"
],
"fields": [
@@ -135,12 +136,19 @@
{
"fieldname": "column_break_14",
"fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "repayment_schedule_name",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "label": "Repayment Schedule Name",
+ "read_only": 1
}
],
"in_create": 1,
"is_submittable": 1,
"links": [],
- "modified": "2020-02-07 01:22:06.924125",
+ "modified": "2020-04-10 18:31:02.369857",
"modified_by": "Administrator",
"module": "Loan Management",
"name": "Loan Interest Accrual",
diff --git a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py
index b8e6dab..094b9c6 100644
--- a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py
+++ b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py
@@ -27,8 +27,14 @@
self.make_gl_entries()
def on_cancel(self):
+ if self.repayment_schedule_name:
+ self.update_is_accrued()
+
self.make_gl_entries(cancel=1)
+ def update_is_accrued(self):
+ frappe.db.set_value('Repayment Schedule', self.repayment_schedule_name, 'is_accrued', 0)
+
def make_gl_entries(self, cancel=0, adv_adj=0):
gle_map = []
@@ -83,9 +89,19 @@
interest_per_day = (pending_principal_amount * loan.rate_of_interest) / (days_in_year(get_datetime(posting_date).year) * 100)
payable_interest = interest_per_day * no_of_days
- make_loan_interest_accrual_entry(loan.name, loan.applicant_type, loan.applicant,loan.interest_income_account,
- loan.loan_account, pending_principal_amount, payable_interest, process_loan_interest = process_loan_interest,
- posting_date=posting_date)
+ args = frappe._dict({
+ 'loan': loan.name,
+ 'applicant_type': loan.applicant_type,
+ 'applicant': loan.applicant,
+ 'interest_income_account': loan.interest_income_account,
+ 'loan_account': loan.loan_account,
+ 'pending_principal_amount': pending_principal_amount,
+ 'interest_amount': payable_interest,
+ 'process_loan_interest': process_loan_interest,
+ 'posting_date': posting_date
+ })
+
+ make_loan_interest_accrual_entry(args)
def make_accrual_interest_entry_for_demand_loans(posting_date, process_loan_interest, open_loans=None, loan_type=None):
query_filters = {
@@ -107,49 +123,71 @@
for loan in open_loans:
calculate_accrual_amount_for_demand_loans(loan, posting_date, process_loan_interest)
-def make_accrual_interest_entry_for_term_loans(posting_date=None):
+def make_accrual_interest_entry_for_term_loans(posting_date, process_loan_interest, term_loan=None, loan_type=None):
curr_date = posting_date or add_days(nowdate(), 1)
- term_loans = frappe.db.sql("""SELECT l.name, l.total_payment, l.total_amount_paid, l.loan_account,
- l.interest_income_account, l.is_term_loan, l.disbursement_date, l.applicant_type, l.applicant,
- l.rate_of_interest, l.total_interest_payable, l.repayment_start_date, rs.name as payment_entry,
- rs.payment_date, rs.principal_amount, rs.interest_amount, rs.is_accrued , rs.balance_loan_amount
- FROM `tabLoan` l, `tabRepayment Schedule` rs
- WHERE rs.parent = l.name
- AND l.docstatus=1
- AND l.is_term_loan =1
- AND rs.payment_date <= %s
- AND rs.is_accrued=0
- AND l.status = 'Disbursed'""", (curr_date), as_dict=1)
+ term_loans = get_term_loans(curr_date, term_loan, loan_type)
accrued_entries = []
for loan in term_loans:
accrued_entries.append(loan.payment_entry)
- make_loan_interest_accrual_entry(loan.name, loan.applicant_type, loan.applicant,loan.interest_income_account,
- loan.loan_account, loan.principal_amount + loan.balance_loan_amount, loan.interest_amount,
- payable_principal = loan.principal_amount , posting_date=posting_date)
+ args = frappe._dict({
+ 'loan': loan.name,
+ 'applicant_type': loan.applicant_type,
+ 'applicant': loan.applicant,
+ 'interest_income_account': loan.interest_income_account,
+ 'loan_account': loan.loan_account,
+ 'interest_amount': loan.interest_amount,
+ 'payable_principal': loan.principal_amount,
+ 'process_loan_interest': process_loan_interest,
+ 'repayment_schedule_name': loan.payment_entry,
+ 'posting_date': posting_date
+ })
+
+ make_loan_interest_accrual_entry(args)
if accrued_entries:
frappe.db.sql("""UPDATE `tabRepayment Schedule`
SET is_accrued = 1 where name in (%s)""" #nosec
% ", ".join(['%s']*len(accrued_entries)), tuple(accrued_entries))
-def make_loan_interest_accrual_entry(loan, applicant_type, applicant, interest_income_account, loan_account,
- pending_principal_amount, interest_amount, payable_principal=None, process_loan_interest=None, posting_date=None):
- loan_interest_accrual = frappe.new_doc("Loan Interest Accrual")
- loan_interest_accrual.loan = loan
- loan_interest_accrual.applicant_type = applicant_type
- loan_interest_accrual.applicant = applicant
- loan_interest_accrual.interest_income_account = interest_income_account
- loan_interest_accrual.loan_account = loan_account
- loan_interest_accrual.pending_principal_amount = flt(pending_principal_amount, 2)
- loan_interest_accrual.interest_amount = flt(interest_amount, 2)
- loan_interest_accrual.posting_date = posting_date or nowdate()
- loan_interest_accrual.process_loan_interest_accrual = process_loan_interest
+def get_term_loans(date, term_loan=None, loan_type=None):
+ condition = ''
- if payable_principal:
- loan_interest_accrual.payable_principal_amount = payable_principal
+ if term_loan:
+ condition +=' AND l.name = %s' % frappe.db.escape(term_loan)
+
+ if loan_type:
+ condition += ' AND l.loan_type = %s' % frappe.db.escape(loan_type)
+
+ term_loans = frappe.db.sql("""SELECT l.name, l.total_payment, l.total_amount_paid, l.loan_account,
+ l.interest_income_account, l.is_term_loan, l.disbursement_date, l.applicant_type, l.applicant,
+ l.rate_of_interest, l.total_interest_payable, l.repayment_start_date, rs.name as payment_entry,
+ rs.payment_date, rs.principal_amount, rs.interest_amount, rs.is_accrued , rs.balance_loan_amount
+ FROM `tabLoan` l, `tabRepayment Schedule` rs
+ WHERE rs.parent = l.name
+ AND l.docstatus=1
+ AND l.is_term_loan =1
+ AND rs.payment_date <= %s
+ AND rs.is_accrued=0 {0}
+ AND l.status = 'Disbursed'""".format(condition), (getdate(date)), as_dict=1)
+
+ return term_loans
+
+def make_loan_interest_accrual_entry(args):
+ loan_interest_accrual = frappe.new_doc("Loan Interest Accrual")
+ loan_interest_accrual.loan = args.loan
+ loan_interest_accrual.applicant_type = args.applicant_type
+ loan_interest_accrual.applicant = args.applicant
+ loan_interest_accrual.interest_income_account = args.interest_income_account
+ loan_interest_accrual.loan_account = args.loan_account
+ loan_interest_accrual.pending_principal_amount = flt(args.pending_principal_amount, 2)
+ loan_interest_accrual.interest_amount = flt(args.interest_amount, 2)
+ loan_interest_accrual.posting_date = args.posting_date or nowdate()
+ loan_interest_accrual.process_loan_interest_accrual = args.process_loan_interest
+ loan_interest_accrual.repayment_schedule_name = args.repayment_schedule_name
+ loan_interest_accrual.payable_principal_amount = args.payable_principal
loan_interest_accrual.save()
loan_interest_accrual.submit()
diff --git a/erpnext/loan_management/doctype/loan_interest_accrual/test_loan_interest_accrual.py b/erpnext/loan_management/doctype/loan_interest_accrual/test_loan_interest_accrual.py
index e681ae4..2afed08 100644
--- a/erpnext/loan_management/doctype/loan_interest_accrual/test_loan_interest_accrual.py
+++ b/erpnext/loan_management/doctype/loan_interest_accrual/test_loan_interest_accrual.py
@@ -7,8 +7,8 @@
from frappe.utils import (nowdate, add_days, get_datetime, get_first_day, get_last_day, date_diff, flt, add_to_date)
from erpnext.loan_management.doctype.loan.test_loan import (create_loan_type, create_loan_security_pledge, create_loan_security_price,
make_loan_disbursement_entry, create_loan_accounts, create_loan_security_type, create_loan_security, create_demand_loan)
-from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual
-from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import (make_accrual_interest_entry_for_term_loans, days_in_year)
+from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_demand_loans
+from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import days_in_year
from erpnext.selling.doctype.customer.test_customer import get_customer_dict
class TestLoanInterestAccrual(unittest.TestCase):
@@ -54,7 +54,7 @@
make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=first_date)
- process_loan_interest_accrual(posting_date=last_date)
+ process_loan_interest_accrual_for_demand_loans(posting_date=last_date)
loan_interest_accural = frappe.get_doc("Loan Interest Accrual", {'loan': loan.name})
diff --git a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
index a70e312..2d2ca4c 100644
--- a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
+++ b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
@@ -210,7 +210,7 @@
)
if gle_map:
- make_gl_entries(gle_map, cancel=cancel, adv_adj=adv_adj)
+ make_gl_entries(gle_map, cancel=cancel, adv_adj=adv_adj, merge_entries=False)
def create_repayment_entry(loan, applicant, company, posting_date, loan_type,
payment_type, interest_payable, payable_principal_amount, amount_paid, penalty_amount=None):
@@ -223,7 +223,7 @@
"posting_date": posting_date,
"applicant": applicant,
"penalty_amount": penalty_amount,
- "interets_payable": interest_payable,
+ "interst_payable": interest_payable,
"payable_principal_amount": payable_principal_amount,
"amount_paid": amount_paid,
"loan_type": loan_type
@@ -236,7 +236,8 @@
fields=["name", "interest_amount", "posting_date", "payable_principal_amount"],
filters = {
"loan": against_loan,
- "is_paid": 0
+ "is_paid": 0,
+ "docstatus": 1
}, order_by="posting_date")
return accrued_interest_entries
@@ -272,7 +273,9 @@
total_pending_interest += entry.interest_amount
payable_principal_amount += entry.payable_principal_amount
- pending_accrual_entries.setdefault(entry.name, entry.interest_amount)
+ pending_accrual_entries.setdefault(entry.name,
+ flt(entry.interest_amount) + flt(entry.payable_principal_amount))
+
final_due_date = due_date
pending_principal_amount = against_loan_doc.total_payment - against_loan_doc.total_principal_paid - against_loan_doc.total_interest_payable
diff --git a/erpnext/loan_management/doctype/loan_security_shortfall/loan_security_shortfall.py b/erpnext/loan_management/doctype/loan_security_shortfall/loan_security_shortfall.py
index b7be84f..ab040f1 100644
--- a/erpnext/loan_management/doctype/loan_security_shortfall/loan_security_shortfall.py
+++ b/erpnext/loan_management/doctype/loan_security_shortfall/loan_security_shortfall.py
@@ -37,17 +37,10 @@
return loan_security_pledge.as_dict()
-def check_for_ltv_shortfall(process_loan_security_shortfall=None):
+def check_for_ltv_shortfall(process_loan_security_shortfall):
update_time = get_datetime()
- if not process_loan_security_shortfall:
- process = frappe.new_doc("Process Loan Security Shortfall")
- process.update_time = update_time
- process.submit()
-
- process_loan_security_shortfall = process.name
-
loan_security_price_map = frappe._dict(frappe.get_all("Loan Security Price",
fields=["loan_security", "loan_security_price"],
filters = {
diff --git a/erpnext/loan_management/doctype/loan_type/loan_type.py b/erpnext/loan_management/doctype/loan_type/loan_type.py
index 14b18ab..208cb19 100644
--- a/erpnext/loan_management/doctype/loan_type/loan_type.py
+++ b/erpnext/loan_management/doctype/loan_type/loan_type.py
@@ -19,3 +19,6 @@
frappe.throw(_("Account {0} does not belong to company {1}").format(frappe.bold(self.get(fieldname)),
frappe.bold(self.company)))
+ if self.get('loan_account') == self.get('payment_account'):
+ frappe.throw(_('Loan Account and Payment Account cannot be same'))
+
diff --git a/erpnext/loan_management/doctype/process_loan_interest_accrual/process_loan_interest_accrual.json b/erpnext/loan_management/doctype/process_loan_interest_accrual/process_loan_interest_accrual.json
index 7f79cb1..0ef098f 100644
--- a/erpnext/loan_management/doctype/process_loan_interest_accrual/process_loan_interest_accrual.json
+++ b/erpnext/loan_management/doctype/process_loan_interest_accrual/process_loan_interest_accrual.json
@@ -9,6 +9,7 @@
"posting_date",
"loan_type",
"loan",
+ "process_type",
"amended_from"
],
"fields": [
@@ -39,11 +40,18 @@
"fieldtype": "Link",
"label": "Loan ",
"options": "Loan"
+ },
+ {
+ "fieldname": "process_type",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "label": "Process Type",
+ "read_only": 1
}
],
"is_submittable": 1,
"links": [],
- "modified": "2020-02-01 08:14:33.978636",
+ "modified": "2020-04-09 22:52:53.911416",
"modified_by": "Administrator",
"module": "Loan Management",
"name": "Process Loan Interest Accrual",
@@ -74,7 +82,6 @@
"write": 1
}
],
- "quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
diff --git a/erpnext/loan_management/doctype/process_loan_interest_accrual/process_loan_interest_accrual.py b/erpnext/loan_management/doctype/process_loan_interest_accrual/process_loan_interest_accrual.py
index 0f33da9..cd3cf7e 100644
--- a/erpnext/loan_management/doctype/process_loan_interest_accrual/process_loan_interest_accrual.py
+++ b/erpnext/loan_management/doctype/process_loan_interest_accrual/process_loan_interest_accrual.py
@@ -6,7 +6,8 @@
import frappe
from frappe.utils import nowdate
from frappe.model.document import Document
-from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import make_accrual_interest_entry_for_demand_loans
+from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import (make_accrual_interest_entry_for_demand_loans,
+ make_accrual_interest_entry_for_term_loans)
class ProcessLoanInterestAccrual(Document):
def on_submit(self):
@@ -14,16 +15,45 @@
if self.loan:
loan_doc = frappe.get_doc('Loan', self.loan)
- open_loans.append(loan_doc)
+ if loan_doc:
+ open_loans.append(loan_doc)
- make_accrual_interest_entry_for_demand_loans(self.posting_date, self.name,
- open_loans = open_loans, loan_type = self.loan_type)
+ if (not self.loan or not loan_doc.is_term_loan) and self.process_type != 'Term Loans':
+ make_accrual_interest_entry_for_demand_loans(self.posting_date, self.name,
+ open_loans = open_loans, loan_type = self.loan_type)
-def process_loan_interest_accrual(posting_date=None, loan_type=None, loan=None):
+ if (not self.loan or loan_doc.is_term_loan) and self.process_type != 'Demand Loans':
+ make_accrual_interest_entry_for_term_loans(self.posting_date, self.name, term_loan=self.loan,
+ loan_type=self.loan_type)
+
+
+def process_loan_interest_accrual_for_demand_loans(posting_date=None, loan_type=None, loan=None):
loan_process = frappe.new_doc('Process Loan Interest Accrual')
loan_process.posting_date = posting_date or nowdate()
loan_process.loan_type = loan_type
+ loan_process.process_type = 'Demand Loans'
loan_process.loan = loan
loan_process.submit()
+def process_loan_interest_accrual_for_term_loans(posting_date=None, loan_type=None, loan=None):
+
+ if not term_loan_accrual_pending(posting_date or nowdate()):
+ return
+
+ loan_process = frappe.new_doc('Process Loan Interest Accrual')
+ loan_process.posting_date = posting_date or nowdate()
+ loan_process.loan_type = loan_type
+ loan_process.process_type = 'Term Loans'
+ loan_process.loan = loan
+
+ loan_process.submit()
+
+def term_loan_accrual_pending(date):
+ pending_accrual = frappe.db.get_value('Repayment Schedule', {
+ 'payment_date': ('<=', date),
+ 'is_accrued': 0
+ })
+
+ return pending_accrual
+
diff --git a/erpnext/loan_management/doctype/process_loan_security_shortfall/process_loan_security_shortfall.py b/erpnext/loan_management/doctype/process_loan_security_shortfall/process_loan_security_shortfall.py
index 417e367..b4aad25 100644
--- a/erpnext/loan_management/doctype/process_loan_security_shortfall/process_loan_security_shortfall.py
+++ b/erpnext/loan_management/doctype/process_loan_security_shortfall/process_loan_security_shortfall.py
@@ -14,4 +14,13 @@
self.set_onload('update_time', get_datetime())
def on_submit(self):
- check_for_ltv_shortfall(process_loan_security_shortfall = self.name)
+ check_for_ltv_shortfall(self.name)
+
+def create_process_loan_security_shortfall():
+ if check_for_secured_loans():
+ process = frappe.new_doc("Process Loan Security Shortfall")
+ process.update_time = get_datetime()
+ process.submit()
+
+def check_for_secured_loans():
+ return frappe.db.count('Loan', {'docstatus': 1, 'is_secured_loan': 1})
diff --git a/erpnext/loan_management/doctype/salary_slip_loan/salary_slip_loan.json b/erpnext/loan_management/doctype/salary_slip_loan/salary_slip_loan.json
index ce020ff..f7e2116 100644
--- a/erpnext/loan_management/doctype/salary_slip_loan/salary_slip_loan.json
+++ b/erpnext/loan_management/doctype/salary_slip_loan/salary_slip_loan.json
@@ -1,4 +1,5 @@
{
+ "actions": [],
"creation": "2019-08-29 18:11:36.829526",
"doctype": "DocType",
"editable_grid": 1,
@@ -49,16 +50,14 @@
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Principal Amount",
- "options": "Company:company:default_currency",
- "read_only": 1
+ "options": "Company:company:default_currency"
},
{
"fieldname": "interest_amount",
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Interest Amount",
- "options": "Company:company:default_currency",
- "read_only": 1
+ "options": "Company:company:default_currency"
},
{
"fieldname": "total_payment",
@@ -79,11 +78,13 @@
"fieldname": "loan_type",
"fieldtype": "Link",
"label": "Loan Type",
- "options": "Loan Type"
+ "options": "Loan Type",
+ "read_only": 1
}
],
"istable": 1,
- "modified": "2019-10-28 09:15:31.174244",
+ "links": [],
+ "modified": "2020-04-09 20:01:53.546364",
"modified_by": "Administrator",
"module": "Loan Management",
"name": "Salary Slip Loan",
diff --git a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json
index 6127ef6..18604e2 100644
--- a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json
+++ b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json
@@ -1,32 +1,34 @@
{
"cards": [
{
- "icon": "fa fa-star",
- "links": "[\n {\n \"dependencies\": [\n \"Item\",\n \"BOM\"\n ],\n \"description\": \"Orders released for production.\",\n \"label\": \"Work Order\",\n \"name\": \"Work Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"BOM\"\n ],\n \"description\": \"Generate Material Requests (MRP) and Work Orders.\",\n \"label\": \"Production Plan\",\n \"name\": \"Production Plan\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Stock Entry\",\n \"name\": \"Stock Entry\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Activity Type\"\n ],\n \"description\": \"Time Sheet for manufacturing.\",\n \"label\": \"Timesheet\",\n \"name\": \"Timesheet\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Job Card\",\n \"name\": \"Job Card\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Production"
+ "hidden": 0,
+ "label": "Production",
+ "links": "[\n {\n \"dependencies\": [\n \"Item\",\n \"BOM\"\n ],\n \"description\": \"Orders released for production.\",\n \"label\": \"Work Order\",\n \"name\": \"Work Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"BOM\"\n ],\n \"description\": \"Generate Material Requests (MRP) and Work Orders.\",\n \"label\": \"Production Plan\",\n \"name\": \"Production Plan\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Stock Entry\",\n \"name\": \"Stock Entry\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Activity Type\"\n ],\n \"description\": \"Time Sheet for manufacturing.\",\n \"label\": \"Timesheet\",\n \"name\": \"Timesheet\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Job Card\",\n \"name\": \"Job Card\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"All Products or Services.\",\n \"label\": \"Item\",\n \"name\": \"Item\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Bill of Materials (BOM)\",\n \"label\": \"Bill of Materials\",\n \"name\": \"BOM\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Where manufacturing operations are carried.\",\n \"label\": \"Workstation\",\n \"name\": \"Workstation\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Details of the operations carried out.\",\n \"label\": \"Operation\",\n \"name\": \"Operation\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Routing\",\n \"name\": \"Routing\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Bill of Materials"
+ "hidden": 0,
+ "label": "Bill of Materials",
+ "links": "[\n {\n \"description\": \"All Products or Services.\",\n \"label\": \"Item\",\n \"name\": \"Item\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Bill of Materials (BOM)\",\n \"label\": \"Bill of Materials\",\n \"name\": \"BOM\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Where manufacturing operations are carried.\",\n \"label\": \"Workstation\",\n \"name\": \"Workstation\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Details of the operations carried out.\",\n \"label\": \"Operation\",\n \"name\": \"Operation\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Routing\",\n \"name\": \"Routing\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-list",
- "links": "[\n {\n \"dependencies\": [\n \"Work Order\"\n ],\n \"doctype\": \"Work Order\",\n \"is_query_report\": true,\n \"label\": \"Open Work Orders\",\n \"name\": \"Open Work Orders\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Work Order\"\n ],\n \"doctype\": \"Work Order\",\n \"is_query_report\": true,\n \"label\": \"Work Orders in Progress\",\n \"name\": \"Work Orders in Progress\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Work Order\"\n ],\n \"doctype\": \"Work Order\",\n \"is_query_report\": true,\n \"label\": \"Issued Items Against Work Order\",\n \"name\": \"Issued Items Against Work Order\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Work Order\"\n ],\n \"doctype\": \"Work Order\",\n \"is_query_report\": true,\n \"label\": \"Completed Work Orders\",\n \"name\": \"Completed Work Orders\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Work Order\"\n ],\n \"doctype\": \"Work Order\",\n \"is_query_report\": true,\n \"label\": \"Production Analytics\",\n \"name\": \"Production Analytics\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"BOM\"\n ],\n \"doctype\": \"BOM\",\n \"is_query_report\": true,\n \"label\": \"BOM Search\",\n \"name\": \"BOM Search\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"BOM\"\n ],\n \"doctype\": \"BOM\",\n \"is_query_report\": true,\n \"label\": \"BOM Stock Report\",\n \"name\": \"BOM Stock Report\",\n \"type\": \"report\"\n }\n]",
- "title": "Reports"
+ "hidden": 0,
+ "label": "Reports",
+ "links": "[\n {\n \"dependencies\": [\n \"Work Order\"\n ],\n \"doctype\": \"Work Order\",\n \"is_query_report\": true,\n \"label\": \"Open Work Orders\",\n \"name\": \"Open Work Orders\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Work Order\"\n ],\n \"doctype\": \"Work Order\",\n \"is_query_report\": true,\n \"label\": \"Work Orders in Progress\",\n \"name\": \"Work Orders in Progress\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Work Order\"\n ],\n \"doctype\": \"Work Order\",\n \"is_query_report\": true,\n \"label\": \"Issued Items Against Work Order\",\n \"name\": \"Issued Items Against Work Order\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Work Order\"\n ],\n \"doctype\": \"Work Order\",\n \"is_query_report\": true,\n \"label\": \"Completed Work Orders\",\n \"name\": \"Completed Work Orders\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Work Order\"\n ],\n \"doctype\": \"Work Order\",\n \"is_query_report\": true,\n \"label\": \"Production Analytics\",\n \"name\": \"Production Analytics\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"BOM\"\n ],\n \"doctype\": \"BOM\",\n \"is_query_report\": true,\n \"label\": \"BOM Search\",\n \"name\": \"BOM Search\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"BOM\"\n ],\n \"doctype\": \"BOM\",\n \"is_query_report\": true,\n \"label\": \"BOM Stock Report\",\n \"name\": \"BOM Stock Report\",\n \"type\": \"report\"\n }\n]"
},
{
- "icon": "fa fa-wrench",
- "links": "[\n {\n \"description\": \"Replace BOM and update latest price in all BOMs\",\n \"label\": \"BOM Update Tool\",\n \"name\": \"BOM Update Tool\",\n \"type\": \"doctype\"\n },\n {\n \"data_doctype\": \"BOM\",\n \"description\": \"Compare BOMs for changes in Raw Materials and Operations\",\n \"label\": \"BOM Comparison Tool\",\n \"name\": \"bom-comparison-tool\",\n \"type\": \"page\"\n }\n]",
- "title": "Tools"
+ "hidden": 0,
+ "label": "Tools",
+ "links": "[\n {\n \"description\": \"Replace BOM and update latest price in all BOMs\",\n \"label\": \"BOM Update Tool\",\n \"name\": \"BOM Update Tool\",\n \"type\": \"doctype\"\n },\n {\n \"data_doctype\": \"BOM\",\n \"description\": \"Compare BOMs for changes in Raw Materials and Operations\",\n \"label\": \"BOM Comparison Tool\",\n \"name\": \"bom-comparison-tool\",\n \"type\": \"page\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Global settings for all manufacturing processes.\",\n \"label\": \"Manufacturing Settings\",\n \"name\": \"Manufacturing Settings\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Settings"
+ "hidden": 0,
+ "label": "Settings",
+ "links": "[\n {\n \"description\": \"Global settings for all manufacturing processes.\",\n \"label\": \"Manufacturing Settings\",\n \"name\": \"Manufacturing Settings\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-facetime-video",
- "links": "[\n {\n \"label\": \"Work Order\",\n \"name\": \"Work Order\",\n \"type\": \"help\",\n \"youtube_id\": \"ZotgLyp2YFY\"\n }\n]",
- "title": "Help"
+ "hidden": 0,
+ "label": "Help",
+ "links": "[\n {\n \"label\": \"Work Order\",\n \"name\": \"Work Order\",\n \"type\": \"help\",\n \"youtube_id\": \"ZotgLyp2YFY\"\n }\n]"
}
],
"category": "Domains",
@@ -40,7 +42,7 @@
"idx": 0,
"is_standard": 1,
"label": "Manufacturing",
- "modified": "2020-03-12 16:30:36.389877",
+ "modified": "2020-04-01 11:28:50.979358",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Manufacturing",
diff --git a/erpnext/non_profit/desk_page/non_profit/non_profit.json b/erpnext/non_profit/desk_page/non_profit/non_profit.json
index 5d759ba..a476857 100644
--- a/erpnext/non_profit/desk_page/non_profit/non_profit.json
+++ b/erpnext/non_profit/desk_page/non_profit/non_profit.json
@@ -1,30 +1,34 @@
{
"cards": [
{
- "icon": "icon-list",
- "links": "[\n {\n \"description\": \"Define various loan types\",\n \"label\": \"Loan Type\",\n \"name\": \"Loan Type\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Loan Application\",\n \"label\": \"Loan Application\",\n \"name\": \"Loan Application\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan\",\n \"name\": \"Loan\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Loan Management"
+ "hidden": 0,
+ "label": "Loan Management",
+ "links": "[\n {\n \"description\": \"Define various loan types\",\n \"label\": \"Loan Type\",\n \"name\": \"Loan Type\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Loan Application\",\n \"label\": \"Loan Application\",\n \"name\": \"Loan Application\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan\",\n \"name\": \"Loan\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Grant information.\",\n \"label\": \"Grant Application\",\n \"name\": \"Grant Application\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Grant Application"
+ "hidden": 0,
+ "label": "Grant Application",
+ "links": "[\n {\n \"description\": \"Grant information.\",\n \"label\": \"Grant Application\",\n \"name\": \"Grant Application\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Member information.\",\n \"label\": \"Member\",\n \"name\": \"Member\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Memebership Details\",\n \"label\": \"Membership\",\n \"name\": \"Membership\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Memebership Type Details\",\n \"label\": \"Membership Type\",\n \"name\": \"Membership Type\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Membership"
+ "hidden": 0,
+ "label": "Membership",
+ "links": "[\n {\n \"description\": \"Member information.\",\n \"label\": \"Member\",\n \"name\": \"Member\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Membership Details\",\n \"label\": \"Membership\",\n \"name\": \"Membership\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Membership Type Details\",\n \"label\": \"Membership Type\",\n \"name\": \"Membership Type\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Billing and Gateway Settings\",\n \"label\": \"Membership Settings\",\n \"name\": \"Membership Settings\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Volunteer information.\",\n \"label\": \"Volunteer\",\n \"name\": \"Volunteer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Volunteer Type information.\",\n \"label\": \"Volunteer Type\",\n \"name\": \"Volunteer Type\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Volunteer"
+ "hidden": 0,
+ "label": "Volunteer",
+ "links": "[\n {\n \"description\": \"Volunteer information.\",\n \"label\": \"Volunteer\",\n \"name\": \"Volunteer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Volunteer Type information.\",\n \"label\": \"Volunteer Type\",\n \"name\": \"Volunteer Type\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-star",
- "links": "[\n {\n \"description\": \"Chapter information.\",\n \"label\": \"Chapter\",\n \"name\": \"Chapter\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]",
- "title": "Chapter"
+ "hidden": 0,
+ "label": "Chapter",
+ "links": "[\n {\n \"description\": \"Chapter information.\",\n \"label\": \"Chapter\",\n \"name\": \"Chapter\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Donor information.\",\n \"label\": \"Donor\",\n \"name\": \"Donor\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Donor Type information.\",\n \"label\": \"Donor Type\",\n \"name\": \"Donor Type\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Donor"
+ "hidden": 0,
+ "label": "Donor",
+ "links": "[\n {\n \"description\": \"Donor information.\",\n \"label\": \"Donor\",\n \"name\": \"Donor\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Donor Type information.\",\n \"label\": \"Donor Type\",\n \"name\": \"Donor Type\",\n \"type\": \"doctype\"\n }\n]"
}
],
"category": "Domains",
@@ -38,7 +42,7 @@
"idx": 0,
"is_standard": 1,
"label": "Non Profit",
- "modified": "2020-03-12 16:30:36.683012",
+ "modified": "2020-04-01 11:28:51.430882",
"modified_by": "Administrator",
"module": "Non Profit",
"name": "Non Profit",
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 9ddd7cc..9ef0b8d 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -661,4 +661,9 @@
erpnext.patches.v12_0.create_irs_1099_field_united_states
erpnext.patches.v12_0.move_bank_account_swift_number_to_bank
erpnext.patches.v12_0.rename_bank_reconciliation_fields # 2020-01-22
-erpnext.patches.v12_0.set_received_qty_in_material_request_as_per_stock_uom
\ No newline at end of file
+erpnext.patches.v12_0.set_received_qty_in_material_request_as_per_stock_uom
+erpnext.patches.v12_0.recalculate_requested_qty_in_bin
+erpnext.patches.v12_0.update_healthcare_refactored_changes
+erpnext.patches.v12_0.set_total_batch_quantity
+erpnext.patches.v12_0.rename_mws_settings_fields
+erpnext.patches.v12_0.set_updated_purpose_in_pick_list
diff --git a/erpnext/patches/v10_0/update_address_template_for_india.py b/erpnext/patches/v10_0/update_address_template_for_india.py
index 145ed45..1ddca93 100644
--- a/erpnext/patches/v10_0/update_address_template_for_india.py
+++ b/erpnext/patches/v10_0/update_address_template_for_india.py
@@ -3,10 +3,10 @@
from __future__ import unicode_literals
import frappe
-from erpnext.regional.india.setup import update_address_template
+from erpnext.regional.address_template.setup import set_up_address_templates
def execute():
if frappe.db.get_value('Company', {'country': 'India'}, 'name'):
address_template = frappe.db.get_value('Address Template', 'India', 'template')
if not address_template or "gstin" not in address_template:
- update_address_template()
+ set_up_address_templates(default_country='India')
diff --git a/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py b/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py
index 31d500e..8889056 100644
--- a/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py
+++ b/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py
@@ -118,7 +118,9 @@
account.insert()
tax_type = account.name
- if tax_type:
+ account_type = frappe.get_cached_value("Account", tax_type, "account_type")
+
+ if tax_type and account_type in ('Tax', 'Chargeable', 'Income Account', 'Expense Account', 'Expenses Included In Valuation'):
item_tax_template.append("taxes", {"tax_type": tax_type, "tax_rate": tax_rate})
item_tax_templates.setdefault(item_tax_template.title, {})
item_tax_templates[item_tax_template.title][tax_type] = tax_rate
diff --git a/erpnext/patches/v12_0/recalculate_requested_qty_in_bin.py b/erpnext/patches/v12_0/recalculate_requested_qty_in_bin.py
new file mode 100644
index 0000000..8267df9
--- /dev/null
+++ b/erpnext/patches/v12_0/recalculate_requested_qty_in_bin.py
@@ -0,0 +1,13 @@
+from __future__ import unicode_literals
+import frappe
+from erpnext.stock.stock_balance import update_bin_qty, get_indented_qty
+
+def execute():
+ bin_details = frappe.db.sql("""
+ SELECT item_code, warehouse
+ FROM `tabBin`""",as_dict=1)
+
+ for entry in bin_details:
+ update_bin_qty(entry.get("item_code"), entry.get("warehouse"), {
+ "indented_qty": get_indented_qty(entry.get("item_code"), entry.get("warehouse"))
+ })
\ No newline at end of file
diff --git a/erpnext/patches/v12_0/rename_mws_settings_fields.py b/erpnext/patches/v12_0/rename_mws_settings_fields.py
new file mode 100644
index 0000000..e08e376
--- /dev/null
+++ b/erpnext/patches/v12_0/rename_mws_settings_fields.py
@@ -0,0 +1,11 @@
+# Copyright (c) 2020, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+import frappe
+
+def execute():
+ count = frappe.db.sql("SELECT COUNT(*) FROM `tabSingles` WHERE doctype='Amazon MWS Settings' AND field='enable_sync';")[0][0]
+ if count == 0:
+ frappe.db.sql("UPDATE `tabSingles` SET field='enable_sync' WHERE doctype='Amazon MWS Settings' AND field='enable_synch';")
+
+ frappe.reload_doc("ERPNext Integrations", "doctype", "Amazon MWS Settings")
diff --git a/erpnext/patches/v12_0/set_against_blanket_order_in_sales_and_purchase_order.py b/erpnext/patches/v12_0/set_against_blanket_order_in_sales_and_purchase_order.py
index 3fccbfa..85202bf 100644
--- a/erpnext/patches/v12_0/set_against_blanket_order_in_sales_and_purchase_order.py
+++ b/erpnext/patches/v12_0/set_against_blanket_order_in_sales_and_purchase_order.py
@@ -1,10 +1,11 @@
import frappe
+
def execute():
- frappe.reload_doc('selling', 'doctype', frappe.scrub('Sales Order Item'))
- frappe.reload_doc('buying', 'doctype', frappe.scrub('Purchase Order Item'))
+ frappe.reload_doc('selling', 'doctype', 'sales_order_item', force=True)
+ frappe.reload_doc('buying', 'doctype', 'purchase_order_item', force=True)
- for doctype in ['Sales Order Item', 'Purchase Order Item']:
+ for doctype in ('Sales Order Item', 'Purchase Order Item'):
frappe.db.sql("""
UPDATE `tab{0}`
SET against_blanket_order = 1
diff --git a/erpnext/patches/v12_0/set_task_status.py b/erpnext/patches/v12_0/set_task_status.py
index 70f6509..dbd7e5a 100644
--- a/erpnext/patches/v12_0/set_task_status.py
+++ b/erpnext/patches/v12_0/set_task_status.py
@@ -1,16 +1,15 @@
import frappe
def execute():
- frappe.reload_doctype('Task')
+ frappe.reload_doctype('Task')
- # add "Completed" if customized
- for doctype in ('Task'):
- property_setter_name = frappe.db.exists('Property Setter', dict(doc_type = doctype, field_name = 'status', property = 'options'))
- if property_setter_name:
- property_setter = frappe.get_doc('Property Setter', property_setter_name)
- if not "Completed" in property_setter.value:
- property_setter.value = property_setter.value + '\nCompleted'
- property_setter.save()
+ # add "Completed" if customized
+ property_setter_name = frappe.db.exists('Property Setter', dict(doc_type='Task', field_name = 'status', property = 'options'))
+ if property_setter_name:
+ property_setter = frappe.get_doc('Property Setter', property_setter_name)
+ if not "Completed" in property_setter.value:
+ property_setter.value = property_setter.value + '\nCompleted'
+ property_setter.save()
- # renamed default status to Completed as status "Closed" is ambiguous
- frappe.db.sql('update tabTask set status = "Completed" where status = "Closed"')
\ No newline at end of file
+ # renamed default status to Completed as status "Closed" is ambiguous
+ frappe.db.sql('update tabTask set status = "Completed" where status = "Closed"')
diff --git a/erpnext/patches/v12_0/set_total_batch_quantity.py b/erpnext/patches/v12_0/set_total_batch_quantity.py
new file mode 100644
index 0000000..d373275
--- /dev/null
+++ b/erpnext/patches/v12_0/set_total_batch_quantity.py
@@ -0,0 +1,11 @@
+import frappe
+
+
+def execute():
+ frappe.reload_doc("stock", "doctype", "batch")
+
+ for batch in frappe.get_all("Batch", fields=["name", "batch_id"]):
+ batch_qty = frappe.db.get_value("Stock Ledger Entry",
+ {"docstatus": 1, "batch_no": batch.batch_id, "is_cancelled": "No"},
+ "sum(actual_qty)") or 0.0
+ frappe.db.set_value("Batch", batch.name, "batch_qty", batch_qty, update_modified=False)
diff --git a/erpnext/patches/v12_0/set_updated_purpose_in_pick_list.py b/erpnext/patches/v12_0/set_updated_purpose_in_pick_list.py
new file mode 100644
index 0000000..63ca540
--- /dev/null
+++ b/erpnext/patches/v12_0/set_updated_purpose_in_pick_list.py
@@ -0,0 +1,11 @@
+# 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("stock", "doctype", "pick_list")
+ frappe.db.sql("""UPDATE `tabPick List` set purpose = 'Delivery'
+ WHERE docstatus = 1 and purpose = 'Delivery against Sales Order' """)
\ No newline at end of file
diff --git a/erpnext/patches/v12_0/update_healthcare_refactored_changes.py b/erpnext/patches/v12_0/update_healthcare_refactored_changes.py
new file mode 100644
index 0000000..02378e0
--- /dev/null
+++ b/erpnext/patches/v12_0/update_healthcare_refactored_changes.py
@@ -0,0 +1,137 @@
+from __future__ import unicode_literals
+import frappe
+from frappe.model.utils.rename_field import rename_field
+from frappe.modules import scrub, get_doctype_module
+
+field_rename_map = {
+ 'Healthcare Settings': [
+ ['patient_master_name', 'patient_name_by'],
+ ['max_visit', 'max_visits'],
+ ['reg_sms', 'send_registration_msg'],
+ ['reg_msg', 'registration_msg'],
+ ['app_con', 'send_appointment_confirmation'],
+ ['app_con_msg', 'appointment_confirmation_msg'],
+ ['no_con', 'avoid_confirmation'],
+ ['app_rem', 'send_appointment_reminder'],
+ ['app_rem_msg', 'appointment_reminder_msg'],
+ ['rem_before', 'remind_before'],
+ ['manage_customer', 'link_customer_to_patient'],
+ ['create_test_on_si_submit', 'create_lab_test_on_si_submit'],
+ ['require_sample_collection', 'create_sample_collection_for_lab_test'],
+ ['require_test_result_approval', 'lab_test_approval_required'],
+ ['manage_appointment_invoice_automatically', 'automate_appointment_invoicing']
+ ],
+ 'Drug Prescription':[
+ ['use_interval', 'usage_interval'],
+ ['in_every', 'interval_uom']
+ ],
+ 'Lab Test Template':[
+ ['sample_quantity', 'sample_qty'],
+ ['sample_collection_details', 'sample_details']
+ ],
+ 'Sample Collection':[
+ ['sample_quantity', 'sample_qty'],
+ ['sample_collection_details', 'sample_details']
+ ],
+ 'Fee Validity': [
+ ['max_visit', 'max_visits']
+ ]
+}
+
+def execute():
+ for dn in field_rename_map:
+ if frappe.db.exists('DocType', dn):
+ if dn == 'Healthcare Settings':
+ frappe.reload_doctype('Healthcare Settings')
+ else:
+ frappe.reload_doc(get_doctype_module(dn), "doctype", scrub(dn))
+
+ for dt, field_list in field_rename_map.items():
+ if frappe.db.exists('DocType', dt):
+ for field in field_list:
+ if dt == 'Healthcare Settings':
+ rename_field(dt, field[0], field[1])
+ elif frappe.db.has_column(dt, field[0]):
+ rename_field(dt, field[0], field[1])
+
+ # first name mandatory in Patient
+ if frappe.db.exists('DocType', 'Patient'):
+ patients = frappe.db.sql("select name, patient_name from `tabPatient`", as_dict=1)
+ frappe.reload_doc('healthcare', 'doctype', 'patient')
+ for entry in patients:
+ name = entry.patient_name.split(' ')
+ frappe.db.set_value('Patient', entry.name, 'first_name', name[0])
+
+ # mark Healthcare Practitioner status as Disabled
+ if frappe.db.exists('DocType', 'Healthcare Practitioner'):
+ practitioners = frappe.db.sql("select name from `tabHealthcare Practitioner` where 'active'= 0", as_dict=1)
+ practitioners_lst = [p.name for p in practitioners]
+ frappe.reload_doc('healthcare', 'doctype', 'healthcare_practitioner')
+ if practitioners_lst:
+ frappe.db.sql("update `tabHealthcare Practitioner` set status = 'Disabled' where name IN %(practitioners)s""", {"practitioners": practitioners_lst})
+
+ # set Clinical Procedure status
+ if frappe.db.exists('DocType', 'Clinical Procedure'):
+ frappe.reload_doc('healthcare', 'doctype', 'clinical_procedure')
+ frappe.db.sql("""
+ UPDATE
+ `tabClinical Procedure`
+ SET
+ docstatus = (CASE WHEN status = 'Cancelled' THEN 2
+ WHEN status = 'Draft' THEN 0
+ ELSE 1
+ END)
+ """)
+
+ # set complaints and diagnosis in table multiselect in Patient Encounter
+ if frappe.db.exists('DocType', 'Patient Encounter'):
+ field_list = [
+ ['visit_department', 'medical_department'],
+ ['type', 'appointment_type']
+ ]
+ encounter_details = frappe.db.sql("""select symptoms, diagnosis, name from `tabPatient Encounter`""", as_dict=True)
+ frappe.reload_doc('healthcare', 'doctype', 'patient_encounter')
+ frappe.reload_doc('healthcare', 'doctype', 'patient_encounter_symptom')
+ frappe.reload_doc('healthcare', 'doctype', 'patient_encounter_diagnosis')
+
+ for field in field_list:
+ if frappe.db.has_column(dt, field[0]):
+ rename_field(dt, field[0], field[1])
+
+ for entry in encounter_details:
+ doc = frappe.get_doc('Patient Encounter', entry.name)
+ symptoms = entry.symptoms.split('\n')
+ for symptom in symptoms:
+ if not frappe.db.exists('Complaint', symptom):
+ frappe.get_doc({
+ 'doctype': 'Complaint',
+ 'complaints': symptom
+ }).insert()
+ row = doc.append('symptoms', {
+ 'complaint': symptom
+ })
+ row.db_update()
+
+ diagnosis = entry.diagnosis.split('\n')
+ for d in diagnosis:
+ if not frappe.db.exists('Diagnosis', d):
+ frappe.get_doc({
+ 'doctype': 'Diagnosis',
+ 'diagnosis': d
+ }).insert()
+ row = doc.append('diagnosis', {
+ 'diagnosis': d
+ })
+ row.db_update()
+ doc.db_update()
+
+ if frappe.db.exists('DocType', 'Fee Validity'):
+ # update fee validity status
+ frappe.db.sql("""
+ UPDATE
+ `tabFee Validity`
+ SET
+ status = (CASE WHEN visited >= max_visits THEN 'Completed'
+ ELSE 'Pending'
+ END)
+ """)
\ No newline at end of file
diff --git a/erpnext/patches/v8_1/gst_fixes.py b/erpnext/patches/v8_1/gst_fixes.py
index 22fa53b..34255eb 100644
--- a/erpnext/patches/v8_1/gst_fixes.py
+++ b/erpnext/patches/v8_1/gst_fixes.py
@@ -1,7 +1,8 @@
from __future__ import unicode_literals
import frappe
from frappe.custom.doctype.custom_field.custom_field import create_custom_field
-from erpnext.regional.india.setup import update_address_template
+from erpnext.regional.address_template.setup import set_up_address_templates
+
def execute():
company = frappe.get_all('Company', filters = {'country': 'India'})
@@ -10,9 +11,10 @@
update_existing_custom_fields()
add_custom_fields()
- update_address_template()
+ set_up_address_templates(default_country='India')
frappe.reload_doc("regional", "print_format", "gst_tax_invoice")
+
def update_existing_custom_fields():
frappe.db.sql("""update `tabCustom Field` set label = 'HSN/SAC'
where fieldname='gst_hsn_code' and label='GST HSN Code'
@@ -34,6 +36,7 @@
where fieldname='gst_hsn_code' and dt in ('Sales Invoice Item', 'Purchase Invoice Item')
""")
+
def add_custom_fields():
hsn_sac_field = dict(fieldname='gst_hsn_code', label='HSN/SAC',
fieldtype='Data', options='item_code.gst_hsn_code', insert_after='description')
diff --git a/erpnext/projects/desk_page/projects/projects.json b/erpnext/projects/desk_page/projects/projects.json
index 13fd1b8..a07cdff 100644
--- a/erpnext/projects/desk_page/projects/projects.json
+++ b/erpnext/projects/desk_page/projects/projects.json
@@ -1,18 +1,19 @@
{
"cards": [
{
- "icon": "fa fa-star",
- "links": "[\n {\n \"description\": \"Project master.\",\n \"label\": \"Project\",\n \"name\": \"Project\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Project activity / task.\",\n \"label\": \"Task\",\n \"name\": \"Task\",\n \"onboard\": 1,\n \"route\": \"#List/Task\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Make project from a template.\",\n \"label\": \"Project Template\",\n \"name\": \"Project Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Define Project type.\",\n \"label\": \"Project Type\",\n \"name\": \"Project Type\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Project\"\n ],\n \"description\": \"Project Update.\",\n \"label\": \"Project Update\",\n \"name\": \"Project Update\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Projects"
+ "hidden": 0,
+ "label": "Projects",
+ "links": "[\n {\n \"description\": \"Project master.\",\n \"label\": \"Project\",\n \"name\": \"Project\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Project activity / task.\",\n \"label\": \"Task\",\n \"name\": \"Task\",\n \"onboard\": 1,\n \"route\": \"#List/Task\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Make project from a template.\",\n \"label\": \"Project Template\",\n \"name\": \"Project Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Define Project type.\",\n \"label\": \"Project Type\",\n \"name\": \"Project Type\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Project\"\n ],\n \"description\": \"Project Update.\",\n \"label\": \"Project Update\",\n \"name\": \"Project Update\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Timesheet for tasks.\",\n \"label\": \"Timesheet\",\n \"name\": \"Timesheet\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Types of activities for Time Logs\",\n \"label\": \"Activity Type\",\n \"name\": \"Activity Type\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Activity Type\"\n ],\n \"description\": \"Cost of various activities\",\n \"label\": \"Activity Cost\",\n \"name\": \"Activity Cost\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Time Tracking"
+ "hidden": 0,
+ "label": "Time Tracking",
+ "links": "[\n {\n \"description\": \"Timesheet for tasks.\",\n \"label\": \"Timesheet\",\n \"name\": \"Timesheet\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Types of activities for Time Logs\",\n \"label\": \"Activity Type\",\n \"name\": \"Activity Type\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Activity Type\"\n ],\n \"description\": \"Cost of various activities\",\n \"label\": \"Activity Cost\",\n \"name\": \"Activity Cost\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-list",
- "links": "[\n {\n \"dependencies\": [\n \"Timesheet\"\n ],\n \"doctype\": \"Timesheet\",\n \"is_query_report\": true,\n \"label\": \"Daily Timesheet Summary\",\n \"name\": \"Daily Timesheet Summary\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Project\"\n ],\n \"doctype\": \"Project\",\n \"is_query_report\": true,\n \"label\": \"Project wise Stock Tracking\",\n \"name\": \"Project wise Stock Tracking\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Project\"\n ],\n \"doctype\": \"Project\",\n \"is_query_report\": true,\n \"label\": \"Project Billing Summary\",\n \"name\": \"Project Billing Summary\",\n \"type\": \"report\"\n }\n]",
- "title": "Reports"
+ "hidden": 0,
+ "label": "Reports",
+ "links": "[\n {\n \"dependencies\": [\n \"Timesheet\"\n ],\n \"doctype\": \"Timesheet\",\n \"is_query_report\": true,\n \"label\": \"Daily Timesheet Summary\",\n \"name\": \"Daily Timesheet Summary\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Project\"\n ],\n \"doctype\": \"Project\",\n \"is_query_report\": true,\n \"label\": \"Project wise Stock Tracking\",\n \"name\": \"Project wise Stock Tracking\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Project\"\n ],\n \"doctype\": \"Project\",\n \"is_query_report\": true,\n \"label\": \"Project Billing Summary\",\n \"name\": \"Project Billing Summary\",\n \"type\": \"report\"\n }\n]"
}
],
"category": "Modules",
@@ -27,7 +28,7 @@
"idx": 0,
"is_standard": 1,
"label": "Projects",
- "modified": "2020-03-12 16:30:41.538685",
+ "modified": "2020-04-01 11:28:51.245756",
"modified_by": "Administrator",
"module": "Projects",
"name": "Projects",
@@ -37,23 +38,23 @@
"shortcuts": [
{
"format": "{} Assigned",
- "is_query_report": 0,
+ "label": "Task",
"link_to": "Task",
"stats_filter": "{\n \"_assign\": [\"like\", '%' + frappe.session.user + '%'],\n \"status\": \"Open\"\n}",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Project",
"link_to": "Project",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Timesheet",
"link_to": "Timesheet",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Project Billing Summary",
"link_to": "Project Billing Summary",
"type": "Report"
}
diff --git a/erpnext/projects/doctype/project/project.json b/erpnext/projects/doctype/project/project.json
index 7d47db3..49abab1 100644
--- a/erpnext/projects/doctype/project/project.json
+++ b/erpnext/projects/doctype/project/project.json
@@ -1,4 +1,5 @@
{
+ "actions": [],
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:project_name",
@@ -435,16 +436,18 @@
},
{
"depends_on": "collect_progress",
- "description": "Message will sent to users to get their status on the project",
+ "description": "Message will be sent to the users to get their status on the Project",
"fieldname": "message",
"fieldtype": "Text",
- "label": "Message"
+ "label": "Message",
+ "mandatory_depends_on": "collect_progress"
}
],
"icon": "fa fa-puzzle-piece",
"idx": 29,
+ "links": [],
"max_attachments": 4,
- "modified": "2019-09-24 15:02:50.208301",
+ "modified": "2020-04-08 22:11:14.552615",
"modified_by": "Administrator",
"module": "Projects",
"name": "Project",
@@ -487,4 +490,4 @@
"sort_order": "DESC",
"timeline_field": "customer",
"track_seen": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/projects/report/billing_summary.py b/erpnext/projects/report/billing_summary.py
index 76379f1..b808268 100644
--- a/erpnext/projects/report/billing_summary.py
+++ b/erpnext/projects/report/billing_summary.py
@@ -53,7 +53,7 @@
def get_data(filters):
data = []
if(filters.from_date > filters.to_date):
- frappe.msgprint(_(" From Date can not be greater than To Date"))
+ frappe.msgprint(_("From Date can not be greater than To Date"))
return data
timesheets = get_timesheets(filters)
diff --git a/erpnext/public/js/conf.js b/erpnext/public/js/conf.js
index 615f6a4..9870f81 100644
--- a/erpnext/public/js/conf.js
+++ b/erpnext/public/js/conf.js
@@ -43,7 +43,6 @@
$.extend(frappe.breadcrumbs.module_map, {
'ERPNext Integrations': 'Integrations',
'Geo': 'Settings',
- 'Accounts': 'Accounting',
'Portal': 'Website',
'Utilities': 'Settings',
'Shopping Cart': 'Website',
diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js
index 3d4c4a6..27a9de9 100644
--- a/erpnext/public/js/controllers/buying.js
+++ b/erpnext/public/js/controllers/buying.js
@@ -85,12 +85,6 @@
filters:{ 'is_sub_contracted_item': 1 }
}
}
- else if (me.frm.doc.material_request_type == "Customer Provided") {
- return{
- query: "erpnext.controllers.queries.item_query",
- filters:{ 'customer': me.frm.doc.customer }
- }
- }
else {
return{
query: "erpnext.controllers.queries.item_query",
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 4397fe4..0c63c33 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -473,6 +473,7 @@
item_code: item.item_code,
barcode: item.barcode,
serial_no: item.serial_no,
+ batch_no: item.batch_no,
set_warehouse: me.frm.doc.set_warehouse,
warehouse: item.warehouse,
customer: me.frm.doc.customer || me.frm.doc.party_name,
@@ -637,6 +638,7 @@
// Add the new list to the serial no. field in grid with each in new line
item.serial_no = valid_serial_nos.join('\n');
+ item.conversion_factor = item.conversion_factor || 1;
refresh_field("serial_no", item.name, item.parentfield);
if(!doc.is_return && cint(user_defaults.set_qty_in_transactions_based_on_serial_no_input)) {
@@ -892,7 +894,7 @@
shipping_rule: function() {
var me = this;
- if(this.frm.doc.shipping_rule) {
+ if(this.frm.doc.shipping_rule && this.frm.doc.shipping_address) {
return this.frm.call({
doc: this.frm.doc,
method: "apply_shipping_rule",
diff --git a/erpnext/public/js/financial_statements.js b/erpnext/public/js/financial_statements.js
index dead309..296c628 100644
--- a/erpnext/public/js/financial_statements.js
+++ b/erpnext/public/js/financial_statements.js
@@ -79,6 +79,39 @@
"options": "Finance Book"
},
{
+ "fieldname":"filter_based_on",
+ "label": __("Filter Based On"),
+ "fieldtype": "Select",
+ "options": ["Fiscal Year", "Date Range"],
+ "default": ["Fiscal Year"],
+ "reqd": 1,
+ on_change: function() {
+ let filter_based_on = frappe.query_report.get_filter_value('filter_based_on');
+ frappe.query_report.toggle_filter_display('from_fiscal_year', filter_based_on === 'Date Range');
+ frappe.query_report.toggle_filter_display('to_fiscal_year', filter_based_on === 'Date Range');
+ frappe.query_report.toggle_filter_display('period_start_date', filter_based_on === 'Fiscal Year');
+ frappe.query_report.toggle_filter_display('period_end_date', filter_based_on === 'Fiscal Year');
+
+ frappe.query_report.refresh();
+ }
+ },
+ {
+ "fieldname":"period_start_date",
+ "label": __("Start Date"),
+ "fieldtype": "Date",
+ "default": frappe.datetime.nowdate(),
+ "hidden": 1,
+ "reqd": 1
+ },
+ {
+ "fieldname":"period_end_date",
+ "label": __("End Date"),
+ "fieldtype": "Date",
+ "default": frappe.datetime.add_months(frappe.datetime.nowdate(), 12),
+ "hidden": 1,
+ "reqd": 1
+ },
+ {
"fieldname":"from_fiscal_year",
"label": __("Start Year"),
"fieldtype": "Link",
diff --git a/erpnext/public/scss/website.scss b/erpnext/public/scss/website.scss
index 7b9a70d..735b417 100644
--- a/erpnext/public/scss/website.scss
+++ b/erpnext/public/scss/website.scss
@@ -78,3 +78,7 @@
z-index: 0;
}
}
+
+.place-order-container {
+ text-align: right;
+}
\ No newline at end of file
diff --git a/erpnext/quality_management/desk_page/quality/quality.json b/erpnext/quality_management/desk_page/quality/quality.json
index 5193e0c..5ee7000 100644
--- a/erpnext/quality_management/desk_page/quality/quality.json
+++ b/erpnext/quality_management/desk_page/quality/quality.json
@@ -1,20 +1,24 @@
{
"cards": [
{
- "links": "[\n {\n \"description\": \"Quality Goal.\",\n \"label\": \"Quality Goal\",\n \"name\": \"Quality Goal\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Quality Procedure.\",\n \"label\": \"Quality Procedure\",\n \"name\": \"Quality Procedure\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tree of Quality Procedures.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Tree of Procedures\",\n \"name\": \"Quality Procedure\",\n \"route\": \"#Tree/Quality Procedure\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Goal and Procedure"
+ "hidden": 0,
+ "label": "Goal and Procedure",
+ "links": "[\n {\n \"description\": \"Quality Goal.\",\n \"label\": \"Quality Goal\",\n \"name\": \"Quality Goal\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Quality Procedure.\",\n \"label\": \"Quality Procedure\",\n \"name\": \"Quality Procedure\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tree of Quality Procedures.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Tree of Procedures\",\n \"name\": \"Quality Procedure\",\n \"route\": \"#Tree/Quality Procedure\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Quality Feedback\",\n \"label\": \"Quality Feedback\",\n \"name\": \"Quality Feedback\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Quality Feedback Template\",\n \"label\": \"Quality Feedback Template\",\n \"name\": \"Quality Feedback Template\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Feedback"
+ "hidden": 0,
+ "label": "Feedback",
+ "links": "[\n {\n \"description\": \"Quality Feedback\",\n \"label\": \"Quality Feedback\",\n \"name\": \"Quality Feedback\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Quality Feedback Template\",\n \"label\": \"Quality Feedback Template\",\n \"name\": \"Quality Feedback Template\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Quality Meeting\",\n \"label\": \"Quality Meeting\",\n \"name\": \"Quality Meeting\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Meeting"
+ "hidden": 0,
+ "label": "Meeting",
+ "links": "[\n {\n \"description\": \"Quality Meeting\",\n \"label\": \"Quality Meeting\",\n \"name\": \"Quality Meeting\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Quality Review\",\n \"label\": \"Quality Review\",\n \"name\": \"Quality Review\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Quality Action\",\n \"label\": \"Quality Action\",\n \"name\": \"Quality Action\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Review and Action"
+ "hidden": 0,
+ "label": "Review and Action",
+ "links": "[\n {\n \"description\": \"Quality Review\",\n \"label\": \"Quality Review\",\n \"name\": \"Quality Review\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Quality Action\",\n \"label\": \"Quality Action\",\n \"name\": \"Quality Action\",\n \"type\": \"doctype\"\n }\n]"
}
],
"category": "Modules",
@@ -29,7 +33,7 @@
"idx": 0,
"is_standard": 1,
"label": "Quality",
- "modified": "2020-03-12 16:30:39.093081",
+ "modified": "2020-04-01 11:28:51.095012",
"modified_by": "Administrator",
"module": "Quality Management",
"name": "Quality",
@@ -38,17 +42,17 @@
"pin_to_top": 0,
"shortcuts": [
{
- "is_query_report": 0,
+ "label": "Quality Goal",
"link_to": "Quality Goal",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Quality Procedure",
"link_to": "Quality Procedure",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Quality Inspection",
"link_to": "Quality Inspection",
"type": "DocType"
}
diff --git a/erpnext/regional/address_template/README.md b/erpnext/regional/address_template/README.md
new file mode 100644
index 0000000..9915734
--- /dev/null
+++ b/erpnext/regional/address_template/README.md
@@ -0,0 +1,18 @@
+To add an **Address Template** for your country, place a new file in this directory:
+
+ * File name: `your_country.html` (lower case with underscores)
+ * File content: a [Jinja Template](http://jinja.pocoo.org/docs/templates/).
+
+All the fields of **Address** (including Custom Fields, if any) will be available to the template. Example:
+
+```jinja
+{{ address_line1 }}<br>
+{% if address_line2 %}{{ address_line2 }}<br>{% endif -%}
+{{ city }}<br>
+{% if state %}{{ state }}<br>{% endif -%}
+{% if pincode %} PIN: {{ pincode }}<br>{% endif -%}
+{{ country }}<br>
+{% if phone %}Phone: {{ phone }}<br>{% endif -%}
+{% if fax %}Fax: {{ fax }}<br>{% endif -%}
+{% if email_id %}Email: {{ email_id }}<br>{% endif -%}
+```
diff --git a/erpnext/healthcare/page/appointment_analytic/__init__.py b/erpnext/regional/address_template/__init__.py
similarity index 100%
copy from erpnext/healthcare/page/appointment_analytic/__init__.py
copy to erpnext/regional/address_template/__init__.py
diff --git a/erpnext/regional/address_template/setup.py b/erpnext/regional/address_template/setup.py
new file mode 100644
index 0000000..9f318de
--- /dev/null
+++ b/erpnext/regional/address_template/setup.py
@@ -0,0 +1,53 @@
+"""Import Address Templates from ./templates directory."""
+import os
+import frappe
+
+def set_up_address_templates(default_country=None):
+ for country, html in get_address_templates():
+ is_default = 1 if country == default_country else 0
+ update_address_template(country, html, is_default)
+
+def get_address_templates():
+ """
+ Return country and path for all HTML files in this directory.
+
+ Returns a list of dicts.
+ """
+ def country(file_name):
+ """Convert 'united_states.html' to 'United States'."""
+ suffix_pos = file_name.find(".html")
+ country_snake_case = file_name[:suffix_pos]
+ country_title_case = " ".join(country_snake_case.split("_")).title()
+ return country_title_case
+
+ def get_file_content(file_name):
+ """Convert 'united_states.html' to '/path/to/united_states.html'."""
+ full_path = os.path.join(template_dir, file_name)
+ with open(full_path, "r") as f:
+ content = f.read()
+ return content
+
+ dir_name = os.path.dirname(__file__)
+ template_dir = os.path.join(dir_name, "templates")
+ file_names = os.listdir(template_dir)
+ html_files = [file for file in file_names if file.endswith(".html")]
+
+ return [(country(file_name), get_file_content(file_name)) for file_name in html_files]
+
+
+def update_address_template(country, html, is_default=0):
+ """Update existing Address Template or create a new one."""
+ if not frappe.db.exists("Country", country):
+ frappe.log_error("Country {} for regional Address Template does not exist.".format(country))
+ return
+
+ if frappe.db.exists("Address Template", country):
+ frappe.db.set_value("Address Template", country, "template", html)
+ frappe.db.set_value("Address Template", country, "is_default", is_default)
+ else:
+ frappe.get_doc(dict(
+ doctype="Address Template",
+ country=country,
+ is_default=is_default,
+ template=html
+ )).insert()
diff --git a/erpnext/regional/germany/address_template.html b/erpnext/regional/address_template/templates/germany.html
similarity index 100%
rename from erpnext/regional/germany/address_template.html
rename to erpnext/regional/address_template/templates/germany.html
diff --git a/erpnext/regional/india/address_template.html b/erpnext/regional/address_template/templates/india.html
similarity index 99%
rename from erpnext/regional/india/address_template.html
rename to erpnext/regional/address_template/templates/india.html
index 55cc9af..ffb9d05 100644
--- a/erpnext/regional/india/address_template.html
+++ b/erpnext/regional/address_template/templates/india.html
@@ -6,4 +6,4 @@
{% if phone %}Phone: {{ phone }}<br>{% endif -%}
{% if fax %}Fax: {{ fax }}<br>{% endif -%}
{% if email_id %}Email: {{ email_id }}<br>{% endif -%}
-{% if gstin %}GSTIN: {{ gstin }}<br>{% endif -%}
\ No newline at end of file
+{% if gstin %}GSTIN: {{ gstin }}<br>{% endif -%}
diff --git a/erpnext/regional/united_states/address_template.html b/erpnext/regional/address_template/templates/united_states.html
similarity index 100%
rename from erpnext/regional/united_states/address_template.html
rename to erpnext/regional/address_template/templates/united_states.html
diff --git a/erpnext/regional/address_template/test_regional_address_template.py b/erpnext/regional/address_template/test_regional_address_template.py
new file mode 100644
index 0000000..8a05ea2
--- /dev/null
+++ b/erpnext/regional/address_template/test_regional_address_template.py
@@ -0,0 +1,45 @@
+from __future__ import unicode_literals
+from unittest import TestCase
+
+import frappe
+from erpnext.regional.address_template.setup import get_address_templates
+from erpnext.regional.address_template.setup import update_address_template
+
+def ensure_country(country):
+ if frappe.db.exists("Country", country):
+ return frappe.get_doc("Country", country)
+ else:
+ c = frappe.get_doc({
+ "doctype": "Country",
+ "country_name": country
+ })
+ c.insert()
+ return c
+
+class TestRegionalAddressTemplate(TestCase):
+ def test_get_address_templates(self):
+ """Get the countries and paths from the templates directory."""
+ templates = get_address_templates()
+ self.assertIsInstance(templates, list)
+ self.assertIsInstance(templates[0], tuple)
+
+ def test_create_address_template(self):
+ """Create a new Address Template."""
+ country = ensure_country("Germany")
+ update_address_template(country.name, "TEST")
+ doc = frappe.get_doc("Address Template", country.name)
+ self.assertEqual(doc.template, "TEST")
+
+ def test_update_address_template(self):
+ """Update an existing Address Template."""
+ country = ensure_country("Germany")
+ if not frappe.db.exists("Address Template", country.name):
+ template = frappe.get_doc({
+ "doctype": "Address Template",
+ "country": country.name,
+ "template": "EXISTING"
+ }).insert()
+
+ update_address_template(country.name, "NEW")
+ doc = frappe.get_doc("Address Template", country.name)
+ self.assertEqual(doc.template, "NEW")
diff --git a/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.py b/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.py
index a2b32fe..9e7a023 100644
--- a/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.py
+++ b/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.py
@@ -277,7 +277,7 @@
def get_itc_details(self, reverse_charge='N'):
itc_amount = frappe.db.sql("""
- select s.gst_category, sum(t.tax_amount) as tax_amount, t.account_head, s.eligibility_for_itc, s.reverse_charge
+ select s.gst_category, sum(t.tax_amount_after_discount_amount) as tax_amount, t.account_head, s.eligibility_for_itc, s.reverse_charge
from `tabPurchase Invoice` s , `tabPurchase Taxes and Charges` t
where s.docstatus = 1 and t.parent = s.name and s.reverse_charge = %s
and month(s.posting_date) = %s and year(s.posting_date) = %s and s.company = %s
@@ -312,7 +312,7 @@
and s.company = %s and s.company_gstin = %s and s.gst_category in ('Unregistered', 'Registered Composition', 'UIN Holders')
group by s.gst_category, s.place_of_supply""", (self.month_no, self.year, self.company, self.gst_details.get("gstin")), as_dict=1)
- inter_state_supply_tax = frappe.db.sql(""" select sum(t.tax_amount) as tax_amount, s.place_of_supply, s.gst_category
+ inter_state_supply_tax = frappe.db.sql(""" select sum(t.tax_amount_after_discount_amount) as tax_amount, s.place_of_supply, s.gst_category
from `tabSales Invoice` s, `tabSales Taxes and Charges` t
where t.parent = s.name and s.docstatus = 1 and month(s.posting_date) = %s and year(s.posting_date) = %s
and s.company = %s and s.company_gstin = %s and s.gst_category in ('Unregistered', 'Registered Composition', 'UIN Holders')
@@ -385,7 +385,7 @@
tax_template = 'Purchase Taxes and Charges'
tax_amounts = frappe.db.sql("""
- select s.gst_category, sum(t.tax_amount) as tax_amount, t.account_head
+ select s.gst_category, sum(t.tax_amount_after_discount_amount) as tax_amount, t.account_head
from `tab{doctype}` s , `tab{template}` t
where s.docstatus = 1 and t.parent = s.name and s.reverse_charge = %s
and month(s.posting_date) = %s and year(s.posting_date) = %s and s.company = %s
diff --git a/erpnext/regional/germany/setup.py b/erpnext/regional/germany/setup.py
index a547136..d6047e8 100644
--- a/erpnext/regional/germany/setup.py
+++ b/erpnext/regional/germany/setup.py
@@ -3,29 +3,4 @@
def setup(company=None, patch=True):
- if not patch:
- update_address_template()
-
-
-def update_address_template():
- """
- Read address template from file. Update existing Address Template or create a
- new one.
- """
- dir_name = os.path.dirname(__file__)
- template_path = os.path.join(dir_name, 'address_template.html')
-
- with open(template_path, 'r') as template_file:
- template_html = template_file.read()
-
- address_template = frappe.db.get_value('Address Template', 'Germany')
-
- if address_template:
- frappe.db.set_value('Address Template', 'Germany', 'template', template_html)
- else:
- # make new html template for Germany
- frappe.get_doc(dict(
- doctype='Address Template',
- country='Germany',
- template=template_html
- )).insert()
+ pass
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index 75f29b8..28b1f8f 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -13,7 +13,6 @@
def setup(company=None, patch=True):
setup_company_independent_fixtures()
if not patch:
- update_address_template()
make_fixtures(company)
# TODO: for all countries
@@ -24,21 +23,6 @@
frappe.enqueue('erpnext.regional.india.setup.add_hsn_sac_codes', now=frappe.flags.in_test)
add_print_formats()
-def update_address_template():
- with open(os.path.join(os.path.dirname(__file__), 'address_template.html'), 'r') as f:
- html = f.read()
-
- address_template = frappe.db.get_value('Address Template', 'India')
- if address_template:
- frappe.db.set_value('Address Template', 'India', 'template', html)
- else:
- # make new html template for India
- frappe.get_doc(dict(
- doctype='Address Template',
- country='India',
- template=html
- )).insert()
-
def add_hsn_sac_codes():
# HSN codes
with open(os.path.join(os.path.dirname(__file__), 'hsn_code_data.json'), 'r') as f:
diff --git a/erpnext/regional/report/datev/datev.py b/erpnext/regional/report/datev/datev.py
index a657912..a8e40cc 100644
--- a/erpnext/regional/report/datev/datev.py
+++ b/erpnext/regional/report/datev/datev.py
@@ -13,6 +13,7 @@
import zlib
import zipfile
import six
+from csv import QUOTE_NONNUMERIC
from six import BytesIO
from six import string_types
import frappe
@@ -80,7 +81,7 @@
gl.posting_date as 'Belegdatum',
gl.voucher_no as 'Belegfeld 1',
- gl.remarks as 'Buchungstext',
+ LEFT(gl.remarks, 60) as 'Buchungstext',
gl.voucher_type as 'Beleginfo - Art 1',
gl.voucher_no as 'Beleginfo - Inhalt 1',
gl.against_voucher_type as 'Beleginfo - Art 2',
@@ -268,7 +269,9 @@
# Do not number rows
index=False,
# Use all columns defined above
- columns=csv_class.COLUMNS
+ columns=csv_class.COLUMNS,
+ # Quote most fields, even currency values with "," separator
+ quoting=QUOTE_NONNUMERIC
)
if not six.PY2:
@@ -285,6 +288,7 @@
def get_header(filters, csv_class):
coa = frappe.get_value("Company", filters.get("company"), "chart_of_accounts")
+ description = filters.get("voucher_type", csv_class.FORMAT_NAME)
coa_used = "04" if "SKR04" in coa else ("03" if "SKR03" in coa else "")
header = [
@@ -323,12 +327,8 @@
frappe.utils.formatdate(filters.get('from_date'), "yyyyMMdd"),
# P = Transaction batch end date (YYYYMMDD)
frappe.utils.formatdate(filters.get('to_date'), "yyyyMMdd"),
- # Q = Description (for example, "January - February 2019 Transactions")
- '"{} - {} {}"'.format(
- frappe.utils.formatdate(filters.get('from_date'), "MMMM yyyy"),
- frappe.utils.formatdate(filters.get('to_date'), "MMMM yyyy"),
- csv_class.FORMAT_NAME
- ),
+ # Q = Description (for example, "Sales Invoice") Max. 30 chars
+ '"{}"'.format(_(description)),
# R = Diktatkürzel
'',
# S = Buchungstyp
diff --git a/erpnext/regional/united_states/setup.py b/erpnext/regional/united_states/setup.py
index cb82b63..6d34402 100644
--- a/erpnext/regional/united_states/setup.py
+++ b/erpnext/regional/united_states/setup.py
@@ -5,12 +5,9 @@
import frappe
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
-
def setup(company=None, patch=True):
make_custom_fields()
add_print_formats()
- update_address_template()
-
def make_custom_fields():
custom_fields = {
@@ -21,22 +18,7 @@
}
create_custom_fields(custom_fields)
-
def add_print_formats():
frappe.reload_doc("regional", "print_format", "irs_1099_form")
frappe.db.sql(""" update `tabPrint Format` set disabled = 0 where
name in('IRS 1099 Form') """)
-
-
-def update_address_template():
- html = """{{ address_line1 }}<br>
- {% if address_line2 %}{{ address_line2 }}<br>{% endif -%}
- {{ city }}, {% if state %}{{ state }}{% endif -%}{% if pincode %} {{ pincode }}<br>{% endif -%}
- {% if country != "United States" %}{{ country|upper }}{% endif -%}
- """
-
- address_template = frappe.db.get_value('Address Template', 'United States')
- if address_template:
- frappe.db.set_value('Address Template', 'United States', 'template', html)
- else:
- frappe.get_doc(dict(doctype='Address Template', country='United States', template=html)).insert()
diff --git a/erpnext/selling/desk_page/retail/retail.json b/erpnext/selling/desk_page/retail/retail.json
index 9838462..9f3912d 100644
--- a/erpnext/selling/desk_page/retail/retail.json
+++ b/erpnext/selling/desk_page/retail/retail.json
@@ -1,8 +1,9 @@
{
"cards": [
{
- "links": "[\n {\n \"description\": \"Setup default values for POS Invoices\",\n \"label\": \"Point-of-Sale Profile\",\n \"name\": \"POS Profile\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"POS Profile\"\n ],\n \"description\": \"Point of Sale\",\n \"label\": \"POS\",\n \"name\": \"pos\",\n \"onboard\": 1,\n \"type\": \"page\"\n },\n {\n \"description\": \"Cashier Closing\",\n \"label\": \"Cashier Closing\",\n \"name\": \"Cashier Closing\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Setup mode of POS (Online / Offline)\",\n \"label\": \"POS Settings\",\n \"name\": \"POS Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"To make Customer based incentive schemes.\",\n \"label\": \"Loyalty Program\",\n \"name\": \"Loyalty Program\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"To view logs of Loyalty Points assigned to a Customer.\",\n \"label\": \"Loyalty Point Entry\",\n \"name\": \"Loyalty Point Entry\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Retail Operations"
+ "hidden": 0,
+ "label": "Retail Operations",
+ "links": "[\n {\n \"description\": \"Setup default values for POS Invoices\",\n \"label\": \"Point-of-Sale Profile\",\n \"name\": \"POS Profile\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"POS Profile\"\n ],\n \"description\": \"Point of Sale\",\n \"label\": \"POS\",\n \"name\": \"pos\",\n \"onboard\": 1,\n \"type\": \"page\"\n },\n {\n \"description\": \"Cashier Closing\",\n \"label\": \"Cashier Closing\",\n \"name\": \"Cashier Closing\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Setup mode of POS (Online / Offline)\",\n \"label\": \"POS Settings\",\n \"name\": \"POS Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"To make Customer based incentive schemes.\",\n \"label\": \"Loyalty Program\",\n \"name\": \"Loyalty Program\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"To view logs of Loyalty Points assigned to a Customer.\",\n \"label\": \"Loyalty Point Entry\",\n \"name\": \"Loyalty Point Entry\",\n \"type\": \"doctype\"\n }\n]"
}
],
"category": "Domains",
@@ -16,7 +17,7 @@
"idx": 0,
"is_standard": 1,
"label": "Retail",
- "modified": "2020-03-12 16:30:36.154297",
+ "modified": "2020-04-01 11:28:50.966145",
"modified_by": "Administrator",
"module": "Selling",
"name": "Retail",
diff --git a/erpnext/selling/desk_page/selling/selling.json b/erpnext/selling/desk_page/selling/selling.json
index 7a0111c..a20806b 100644
--- a/erpnext/selling/desk_page/selling/selling.json
+++ b/erpnext/selling/desk_page/selling/selling.json
@@ -1,36 +1,36 @@
{
"cards": [
{
- "links": "[\n {\n \"description\": \"All Products or Services.\",\n \"label\": \"Item\",\n \"name\": \"Item\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Price List\"\n ],\n \"description\": \"Multiple Item prices.\",\n \"label\": \"Item Price\",\n \"name\": \"Item Price\",\n \"onboard\": 1,\n \"route\": \"#Report/Item Price\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Price List master.\",\n \"label\": \"Price List\",\n \"name\": \"Price List\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tree of Item Groups.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Item Group\",\n \"link\": \"Tree/Item Group\",\n \"name\": \"Item Group\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Bundle items at time of sale.\",\n \"label\": \"Product Bundle\",\n \"name\": \"Product Bundle\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Rules for applying different promotional schemes.\",\n \"label\": \"Promotional Scheme\",\n \"name\": \"Promotional Scheme\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Rules for applying pricing and discount.\",\n \"label\": \"Pricing Rule\",\n \"name\": \"Pricing Rule\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Rules for adding shipping costs.\",\n \"label\": \"Shipping Rule\",\n \"name\": \"Shipping Rule\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Define coupon codes.\",\n \"label\": \"Coupon Code\",\n \"name\": \"Coupon Code\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Items and Pricing"
+ "hidden": 0,
+ "label": "Items and Pricing",
+ "links": "[\n {\n \"description\": \"All Products or Services.\",\n \"label\": \"Item\",\n \"name\": \"Item\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Price List\"\n ],\n \"description\": \"Multiple Item prices.\",\n \"label\": \"Item Price\",\n \"name\": \"Item Price\",\n \"onboard\": 1,\n \"route\": \"#Report/Item Price\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Price List master.\",\n \"label\": \"Price List\",\n \"name\": \"Price List\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tree of Item Groups.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Item Group\",\n \"link\": \"Tree/Item Group\",\n \"name\": \"Item Group\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Bundle items at time of sale.\",\n \"label\": \"Product Bundle\",\n \"name\": \"Product Bundle\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Rules for applying different promotional schemes.\",\n \"label\": \"Promotional Scheme\",\n \"name\": \"Promotional Scheme\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Rules for applying pricing and discount.\",\n \"label\": \"Pricing Rule\",\n \"name\": \"Pricing Rule\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Rules for adding shipping costs.\",\n \"label\": \"Shipping Rule\",\n \"name\": \"Shipping Rule\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Define coupon codes.\",\n \"label\": \"Coupon Code\",\n \"name\": \"Coupon Code\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-cog",
- "links": "[\n {\n \"description\": \"Default settings for selling transactions.\",\n \"label\": \"Selling Settings\",\n \"name\": \"Selling Settings\",\n \"settings\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Template of terms or contract.\",\n \"label\": \"Terms and Conditions Template\",\n \"name\": \"Terms and Conditions\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax template for selling transactions.\",\n \"label\": \"Sales Taxes and Charges Template\",\n \"name\": \"Sales Taxes and Charges Template\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Track Leads by Lead Source.\",\n \"label\": \"Lead Source\",\n \"name\": \"Lead Source\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Customer Group Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Customer Group\",\n \"link\": \"Tree/Customer Group\",\n \"name\": \"Customer Group\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Contacts.\",\n \"label\": \"Contact\",\n \"name\": \"Contact\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Addresses.\",\n \"label\": \"Address\",\n \"name\": \"Address\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Territory Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Territory\",\n \"link\": \"Tree/Territory\",\n \"name\": \"Territory\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Sales campaigns.\",\n \"label\": \"Campaign\",\n \"name\": \"Campaign\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Settings"
+ "hidden": 0,
+ "label": "Settings",
+ "links": "[\n {\n \"description\": \"Default settings for selling transactions.\",\n \"label\": \"Selling Settings\",\n \"name\": \"Selling Settings\",\n \"settings\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Template of terms or contract.\",\n \"label\": \"Terms and Conditions Template\",\n \"name\": \"Terms and Conditions\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax template for selling transactions.\",\n \"label\": \"Sales Taxes and Charges Template\",\n \"name\": \"Sales Taxes and Charges Template\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Track Leads by Lead Source.\",\n \"label\": \"Lead Source\",\n \"name\": \"Lead Source\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Customer Group Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Customer Group\",\n \"link\": \"Tree/Customer Group\",\n \"name\": \"Customer Group\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Contacts.\",\n \"label\": \"Contact\",\n \"name\": \"Contact\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"All Addresses.\",\n \"label\": \"Address\",\n \"name\": \"Address\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Territory Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Territory\",\n \"link\": \"Tree/Territory\",\n \"name\": \"Territory\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Sales campaigns.\",\n \"label\": \"Campaign\",\n \"name\": \"Campaign\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-list",
- "links": "[\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Lead Details\",\n \"name\": \"Lead Details\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Address\"\n ],\n \"doctype\": \"Address\",\n \"is_query_report\": true,\n \"label\": \"Customer Addresses And Contacts\",\n \"name\": \"Address And Contacts\",\n \"route_options\": {\n \"party_type\": \"Customer\"\n },\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"BOM\"\n ],\n \"doctype\": \"BOM\",\n \"is_query_report\": true,\n \"label\": \"BOM Search\",\n \"name\": \"BOM Search\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Available Stock for Packing Items\",\n \"name\": \"Available Stock for Packing Items\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Pending SO Items For Purchase Request\",\n \"name\": \"Pending SO Items For Purchase Request\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customer Credit Balance\",\n \"name\": \"Customer Credit Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customers Without Any Sales Transactions\",\n \"name\": \"Customers Without Any Sales Transactions\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Sales Partners Commission\",\n \"name\": \"Sales Partners Commission\",\n \"type\": \"report\"\n }\n]",
- "title": "Other Reports"
+ "hidden": 0,
+ "label": "Other Reports",
+ "links": "[\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Lead Details\",\n \"name\": \"Lead Details\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Address\"\n ],\n \"doctype\": \"Address\",\n \"is_query_report\": true,\n \"label\": \"Customer Addresses And Contacts\",\n \"name\": \"Address And Contacts\",\n \"route_options\": {\n \"party_type\": \"Customer\"\n },\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"BOM\"\n ],\n \"doctype\": \"BOM\",\n \"is_query_report\": true,\n \"label\": \"BOM Search\",\n \"name\": \"BOM Search\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Available Stock for Packing Items\",\n \"name\": \"Available Stock for Packing Items\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Pending SO Items For Purchase Request\",\n \"name\": \"Pending SO Items For Purchase Request\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customer Credit Balance\",\n \"name\": \"Customer Credit Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customers Without Any Sales Transactions\",\n \"name\": \"Customers Without Any Sales Transactions\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Sales Partners Commission\",\n \"name\": \"Sales Partners Commission\",\n \"type\": \"report\"\n }\n]"
},
{
- "icon": "fa fa-star",
- "links": "[\n {\n \"description\": \"Customer Database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Quotes to Leads or Customers.\",\n \"label\": \"Quotation\",\n \"name\": \"Quotation\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Confirmed orders from Customers.\",\n \"label\": \"Sales Order\",\n \"name\": \"Sales Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Invoices for Costumers.\",\n \"label\": \"Sales Invoice\",\n \"name\": \"Sales Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Blanket Orders from Costumers.\",\n \"label\": \"Blanket Order\",\n \"name\": \"Blanket Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Manage Sales Partners.\",\n \"label\": \"Sales Partner\",\n \"name\": \"Sales Partner\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Manage Sales Person Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Sales Person\",\n \"link\": \"Tree/Sales Person\",\n \"name\": \"Sales Person\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Sales"
+ "hidden": 0,
+ "label": "Sales",
+ "links": "[\n {\n \"description\": \"Customer Database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Quotes to Leads or Customers.\",\n \"label\": \"Quotation\",\n \"name\": \"Quotation\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Confirmed orders from Customers.\",\n \"label\": \"Sales Order\",\n \"name\": \"Sales Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Invoices for Costumers.\",\n \"label\": \"Sales Invoice\",\n \"name\": \"Sales Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Blanket Orders from Costumers.\",\n \"label\": \"Blanket Order\",\n \"name\": \"Blanket Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"description\": \"Manage Sales Partners.\",\n \"label\": \"Sales Partner\",\n \"name\": \"Sales Partner\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"description\": \"Manage Sales Person Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Sales Person\",\n \"link\": \"Tree/Sales Person\",\n \"name\": \"Sales Person\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-table",
- "links": "[\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Analytics\",\n \"name\": \"Sales Analytics\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"icon\": \"fa fa-bar-chart\",\n \"label\": \"Sales Funnel\",\n \"name\": \"sales-funnel\",\n \"onboard\": 1,\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"icon\": \"fa fa-bar-chart\",\n \"is_query_report\": true,\n \"label\": \"Customer Acquisition and Loyalty\",\n \"name\": \"Customer Acquisition and Loyalty\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Inactive Customers\",\n \"name\": \"Inactive Customers\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Ordered Items To Be Delivered\",\n \"name\": \"Ordered Items To Be Delivered\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Person-wise Transaction Summary\",\n \"name\": \"Sales Person-wise Transaction Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Sales History\",\n \"name\": \"Item-wise Sales History\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Quotation\"\n ],\n \"doctype\": \"Quotation\",\n \"is_query_report\": true,\n \"label\": \"Quotation Trends\",\n \"name\": \"Quotation Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Order Trends\",\n \"name\": \"Sales Order Trends\",\n \"type\": \"report\"\n }\n]",
- "title": "Key Reports"
+ "hidden": 0,
+ "label": "Key Reports",
+ "links": "[\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Analytics\",\n \"name\": \"Sales Analytics\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"icon\": \"fa fa-bar-chart\",\n \"label\": \"Sales Funnel\",\n \"name\": \"sales-funnel\",\n \"onboard\": 1,\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"icon\": \"fa fa-bar-chart\",\n \"is_query_report\": true,\n \"label\": \"Customer Acquisition and Loyalty\",\n \"name\": \"Customer Acquisition and Loyalty\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Inactive Customers\",\n \"name\": \"Inactive Customers\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Ordered Items To Be Delivered\",\n \"name\": \"Ordered Items To Be Delivered\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Person-wise Transaction Summary\",\n \"name\": \"Sales Person-wise Transaction Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Sales History\",\n \"name\": \"Item-wise Sales History\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Quotation\"\n ],\n \"doctype\": \"Quotation\",\n \"is_query_report\": true,\n \"label\": \"Quotation Trends\",\n \"name\": \"Quotation Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Order Trends\",\n \"name\": \"Sales Order Trends\",\n \"type\": \"report\"\n }\n]"
}
],
"category": "Modules",
"charts": [
{
"chart_name": "Income",
- "label": "Income",
- "size": "Full"
+ "label": "Income"
}
],
"creation": "2020-01-28 11:49:12.092882",
@@ -43,7 +43,7 @@
"idx": 0,
"is_standard": 1,
"label": "Selling",
- "modified": "2020-03-12 16:30:38.207013",
+ "modified": "2020-04-01 11:28:51.047373",
"modified_by": "Administrator",
"module": "Selling",
"name": "Selling",
@@ -52,32 +52,32 @@
"pin_to_top": 0,
"shortcuts": [
{
- "is_query_report": 0,
+ "label": "Sales Invoice",
"link_to": "Sales Invoice",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Sales Order",
"link_to": "Sales Order",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Quotation",
"link_to": "Quotation",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Delivery Note",
"link_to": "Delivery Note",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Accounts Receivable",
"link_to": "Accounts Receivable",
"type": "Report"
},
{
- "is_query_report": 0,
+ "label": "Sales Register",
"link_to": "Sales Register",
"type": "Report"
}
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index 02667e8..50e719f 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -150,7 +150,7 @@
contact.save()
else:
- lead.lead_name = lead.lead_name.split(" ")
+ lead.lead_name = lead.lead_name.lstrip().split(" ")
lead.first_name = lead.lead_name[0]
lead.last_name = " ".join(lead.lead_name[1:])
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index ef2d19a..05e4aa8 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -1036,7 +1036,7 @@
},
}, target_doc)
- doc.purpose = 'Delivery against Sales Order'
+ doc.purpose = 'Delivery'
doc.set_item_locations()
diff --git a/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json b/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json
index ac0a4b2..253d711 100644
--- a/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json
+++ b/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json
@@ -12,7 +12,7 @@
"idx": 0,
"is_standard": 1,
"label": "ERPNext Settings",
- "modified": "2020-03-12 18:03:17.126782",
+ "modified": "2020-04-01 11:28:51.400851",
"modified_by": "Administrator",
"module": "Setup",
"name": "ERPNext Settings",
@@ -22,89 +22,89 @@
"shortcuts": [
{
"icon": "octicon octicon-rocket",
- "is_query_report": 0,
+ "label": "Projects Settings",
"link_to": "Projects Settings",
"type": "DocType"
},
{
"icon": "octicon octicon-repo",
- "is_query_report": 0,
+ "label": "Accounts Settings",
"link_to": "Accounts Settings",
"type": "DocType"
},
{
"icon": "octicon octicon-package",
- "is_query_report": 0,
+ "label": "Stock Settings",
"link_to": "Stock Settings",
"type": "DocType"
},
{
"icon": "octicon octicon-organization",
- "is_query_report": 0,
+ "label": "HR Settings",
"link_to": "HR Settings",
"type": "DocType"
},
{
"icon": "octicon octicon-tag",
- "is_query_report": 0,
+ "label": "Selling Settings",
"link_to": "Selling Settings",
"type": "DocType"
},
{
"icon": "octicon octicon-briefcase",
- "is_query_report": 0,
+ "label": "Buying Settings",
"link_to": "Buying Settings",
"type": "DocType"
},
{
"icon": "fa fa-life-ring",
- "is_query_report": 0,
+ "label": "Support Settings",
"link_to": "Support Settings",
"type": "DocType"
},
{
"icon": "fa fa-shopping-cart",
- "is_query_report": 0,
+ "label": "Shopping Cart Settings",
"link_to": "Shopping Cart Settings",
"type": "DocType"
},
{
"icon": "fa fa-globe",
- "is_query_report": 0,
+ "label": "Portal Settings",
"link_to": "Portal Settings",
"type": "DocType"
},
{
"icon": "octicon octicon-tools",
- "is_query_report": 0,
+ "label": "Manufacturing Settings",
"link_to": "Manufacturing Settings",
"restrict_to_domain": "Manufacturing",
"type": "DocType"
},
{
"icon": "octicon octicon-mortar-board",
- "is_query_report": 0,
+ "label": "Education Settings",
"link_to": "Education Settings",
"restrict_to_domain": "Education",
"type": "DocType"
},
{
"icon": "fa fa-bed",
- "is_query_report": 0,
+ "label": "Hotel Settings",
"link_to": "Hotel Settings",
"restrict_to_domain": "Hospitality",
"type": "DocType"
},
{
"icon": "fa fa-heartbeat",
- "is_query_report": 0,
+ "label": "Healthcare Settings",
"link_to": "Healthcare Settings",
"restrict_to_domain": "Healthcare",
"type": "DocType"
},
{
"icon": "fa fa-cog",
- "is_query_report": 0,
+ "label": "Domain Settings",
"link_to": "Domain Settings",
"type": "DocType"
}
diff --git a/erpnext/setup/desk_page/getting_started/getting_started.json b/erpnext/setup/desk_page/getting_started/getting_started.json
index b045b5d..63d8984 100644
--- a/erpnext/setup/desk_page/getting_started/getting_started.json
+++ b/erpnext/setup/desk_page/getting_started/getting_started.json
@@ -1,40 +1,49 @@
{
"cards": [
{
- "links": "[\n {\n \"label\": \"Patient\",\n \"name\": \"Patient\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Diagnosis\",\n \"name\": \"Diagnosis\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]",
- "title": "Healthcare"
+ "hidden": 0,
+ "label": "Healthcare",
+ "links": "[\n {\n \"label\": \"Patient\",\n \"name\": \"Patient\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Diagnosis\",\n \"name\": \"Diagnosis\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Crop\",\n \"name\": \"Crop\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Crop Cycle\",\n \"name\": \"Crop Cycle\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Location\",\n \"name\": \"Location\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Fertilizer\",\n \"name\": \"Fertilizer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]",
- "title": "Agriculture"
+ "hidden": 0,
+ "label": "Agriculture",
+ "links": "[\n {\n \"label\": \"Crop\",\n \"name\": \"Crop\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Crop Cycle\",\n \"name\": \"Crop Cycle\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Location\",\n \"name\": \"Location\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Fertilizer\",\n \"name\": \"Fertilizer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Warehouse\",\n \"name\": \"Warehouse\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Brand\",\n \"name\": \"Brand\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Unit of Measure (UOM)\",\n \"name\": \"UOM\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Stock Reconciliation\",\n \"name\": \"Stock Reconciliation\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]",
- "title": "Stock"
+ "hidden": 0,
+ "label": "Education",
+ "links": "[\n {\n \"label\": \"Student\",\n \"name\": \"Student\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Course\",\n \"name\": \"Course\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Instructor\",\n \"name\": \"Instructor\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Room\",\n \"name\": \"Room\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Employee\",\n \"name\": \"Employee\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"hide_count\": true,\n \"label\": \"Employee Attendance Tool\",\n \"name\": \"Employee Attendance Tool\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Salary Structure\",\n \"name\": \"Salary Structure\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]",
- "title": "Human Resources"
+ "hidden": 0,
+ "label": "Non Profit",
+ "links": "[\n {\n \"description\": \"Member information.\",\n \"label\": \"Member\",\n \"name\": \"Member\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Volunteer information.\",\n \"label\": \"Volunteer\",\n \"name\": \"Volunteer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Chapter information.\",\n \"label\": \"Chapter\",\n \"name\": \"Chapter\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Donor information.\",\n \"label\": \"Donor\",\n \"name\": \"Donor\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Database of potential customers.\",\n \"label\": \"Lead\",\n \"name\": \"Lead\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Customer Group Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Customer Group\",\n \"link\": \"Tree/Customer Group\",\n \"name\": \"Customer Group\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Territory Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Territory\",\n \"link\": \"Tree/Territory\",\n \"name\": \"Territory\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]",
- "title": "CRM"
+ "hidden": 0,
+ "label": "Stock",
+ "links": "[\n {\n \"label\": \"Warehouse\",\n \"name\": \"Warehouse\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Brand\",\n \"name\": \"Brand\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Unit of Measure (UOM)\",\n \"name\": \"UOM\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Stock Reconciliation\",\n \"name\": \"Stock Reconciliation\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Item\",\n \"name\": \"Item\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customer database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Supplier database.\",\n \"label\": \"Supplier\",\n \"name\": \"Supplier\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Company (not Customer or Supplier) master.\",\n \"label\": \"Company\",\n \"name\": \"Company\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tree of financial accounts.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Chart of Accounts\",\n \"name\": \"Account\",\n \"onboard\": 1,\n \"route\": \"#Tree/Account\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Create Opening Sales and Purchase Invoices\",\n \"label\": \"Opening Invoice Creation Tool\",\n \"name\": \"Opening Invoice Creation Tool\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]",
- "title": "Accounting"
+ "hidden": 0,
+ "label": "Human Resources",
+ "links": "[\n {\n \"label\": \"Employee\",\n \"name\": \"Employee\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"hide_count\": true,\n \"label\": \"Employee Attendance Tool\",\n \"name\": \"Employee Attendance Tool\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Salary Structure\",\n \"name\": \"Salary Structure\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Student\",\n \"name\": \"Student\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Course\",\n \"name\": \"Course\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Instructor\",\n \"name\": \"Instructor\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Room\",\n \"name\": \"Room\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]",
- "title": "Education"
+ "hidden": 0,
+ "label": "CRM",
+ "links": "[\n {\n \"description\": \"Database of potential customers.\",\n \"label\": \"Lead\",\n \"name\": \"Lead\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Customer Group Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Customer Group\",\n \"link\": \"Tree/Customer Group\",\n \"name\": \"Customer Group\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Manage Territory Tree.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Territory\",\n \"link\": \"Tree/Territory\",\n \"name\": \"Territory\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Import Data from CSV / Excel files.\",\n \"icon\": \"octicon octicon-cloud-upload\",\n \"label\": \"Import Data\",\n \"name\": \"Data Import\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Import Chart Of Accounts from CSV / Excel files\",\n \"labe\": \"Chart Of Accounts Importer\",\n \"label\": \"Chart of Accounts Importer\",\n \"name\": \"Chart of Accounts Importer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Letter Heads for print templates.\",\n \"label\": \"Letter Head\",\n \"name\": \"Letter Head\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Add / Manage Email Accounts.\",\n \"label\": \"Email Account\",\n \"name\": \"Email Account\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]",
- "title": "Data Import and Settings"
+ "hidden": 0,
+ "label": "Accounting",
+ "links": "[\n {\n \"label\": \"Item\",\n \"name\": \"Item\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customer database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Supplier database.\",\n \"label\": \"Supplier\",\n \"name\": \"Supplier\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Company (not Customer or Supplier) master.\",\n \"label\": \"Company\",\n \"name\": \"Company\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tree of financial accounts.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Chart of Accounts\",\n \"name\": \"Account\",\n \"onboard\": 1,\n \"route\": \"#Tree/Account\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Create Opening Sales and Purchase Invoices\",\n \"label\": \"Opening Invoice Creation Tool\",\n \"name\": \"Opening Invoice Creation Tool\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Member information.\",\n \"label\": \"Member\",\n \"name\": \"Member\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Volunteer information.\",\n \"label\": \"Volunteer\",\n \"name\": \"Volunteer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Chapter information.\",\n \"label\": \"Chapter\",\n \"name\": \"Chapter\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Donor information.\",\n \"label\": \"Donor\",\n \"name\": \"Donor\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]",
- "title": "Non Profit"
+ "hidden": 0,
+ "label": "Data Import and Settings",
+ "links": "[\n {\n \"description\": \"Import Data from CSV / Excel files.\",\n \"icon\": \"octicon octicon-cloud-upload\",\n \"label\": \"Import Data\",\n \"name\": \"Data Import\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Import Chart Of Accounts from CSV / Excel files\",\n \"labe\": \"Chart Of Accounts Importer\",\n \"label\": \"Chart of Accounts Importer\",\n \"name\": \"Chart of Accounts Importer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Letter Heads for print templates.\",\n \"label\": \"Letter Head\",\n \"name\": \"Letter Head\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Add / Manage Email Accounts.\",\n \"label\": \"Email Account\",\n \"name\": \"Email Account\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n }\n]"
}
],
"category": "Modules",
@@ -54,7 +63,7 @@
"idx": 0,
"is_standard": 1,
"label": "Getting Started",
- "modified": "2020-03-23 11:20:49.161823",
+ "modified": "2020-04-01 11:30:19.763099",
"modified_by": "Administrator",
"module": "Setup",
"name": "Getting Started",
@@ -63,32 +72,32 @@
"pin_to_top": 1,
"shortcuts": [
{
- "is_query_report": 0,
+ "label": "Item",
"link_to": "Item",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Customer",
"link_to": "Customer",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Supplier",
"link_to": "Supplier",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Sales Invoice",
"link_to": "Sales Invoice",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Dashboard",
"link_to": "dashboard",
"type": "Page"
},
{
- "is_query_report": 0,
+ "label": "Leaderboard",
"link_to": "leaderboard",
"type": "Page"
}
diff --git a/erpnext/setup/setup_wizard/operations/install_fixtures.py b/erpnext/setup/setup_wizard/operations/install_fixtures.py
index ebd7b50..e4986e3 100644
--- a/erpnext/setup/setup_wizard/operations/install_fixtures.py
+++ b/erpnext/setup/setup_wizard/operations/install_fixtures.py
@@ -8,9 +8,11 @@
from frappe import _
from frappe.desk.page.setup_wizard.setup_wizard import make_records
from frappe.utils import cstr, getdate
-from erpnext.accounts.doctype.account.account import RootNotEditable
from frappe.desk.doctype.global_search_settings.global_search_settings import update_global_search_doctypes
+from erpnext.accounts.doctype.account.account import RootNotEditable
+from erpnext.regional.address_template.setup import set_up_address_templates
+
default_lead_sources = ["Existing Customer", "Reference", "Advertisement",
"Cold Calling", "Exhibition", "Supplier Reference", "Mass Mailing",
"Customer's Vendor", "Campaign", "Walk In"]
@@ -30,7 +32,7 @@
{ 'doctype': 'Domain', 'domain': 'Agriculture'},
{ 'doctype': 'Domain', 'domain': 'Non Profit'},
- # address template
+ # ensure at least an empty Address Template exists for this Country
{'doctype':"Address Template", "country": country},
# item group
@@ -269,12 +271,11 @@
# Records for the Supplier Scorecard
from erpnext.buying.doctype.supplier_scorecard.supplier_scorecard import make_default_records
+
make_default_records()
-
make_records(records)
-
+ set_up_address_templates(default_country=country)
set_more_defaults()
-
update_global_search_doctypes()
# path = frappe.get_app_path('erpnext', 'regional', frappe.scrub(country))
diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py
index 1dac9bd..e11e1bb 100644
--- a/erpnext/shopping_cart/cart.py
+++ b/erpnext/shopping_cart/cart.py
@@ -38,14 +38,14 @@
addresses = get_address_docs(party=party)
if not doc.customer_address and addresses:
- update_cart_address("customer_address", addresses[0].name)
+ update_cart_address("billing", addresses[0].name)
return {
"doc": decorate_quotation_doc(doc),
"shipping_addresses": [{"name": address.name, "display": address.display}
- for address in addresses],
+ for address in addresses if address.address_type == "Shipping"],
"billing_addresses": [{"name": address.name, "display": address.display}
- for address in addresses],
+ for address in addresses if address.address_type == "Billing"],
"shipping_rules": get_applicable_shipping_rules(party),
"cart_settings": frappe.get_cached_doc("Shopping Cart Settings")
}
@@ -64,6 +64,9 @@
# company used to create customer accounts
frappe.defaults.set_user_default("company", quotation.company)
+ if not (quotation.shipping_address_name or quotation.customer_address):
+ frappe.throw(_("Set Shipping Address or Billing Address"))
+
from erpnext.selling.doctype.quotation.quotation import _make_sales_order
sales_order = frappe.get_doc(_make_sales_order(quotation.name, ignore_permissions=True))
sales_order.payment_schedule = []
@@ -194,21 +197,18 @@
return frappe.db.get_value('Terms and Conditions', terms_name, 'terms')
@frappe.whitelist()
-def update_cart_address(address_fieldname, address_name):
+def update_cart_address(address_type, address_name):
quotation = _get_cart_quotation()
address_display = get_address_display(frappe.get_doc("Address", address_name).as_dict())
- if address_fieldname == "shipping_address_name":
- quotation.shipping_address_name = address_name
- quotation.shipping_address = address_display
-
- if not quotation.customer_address:
- address_fieldname == "customer_address"
-
- if address_fieldname == "customer_address":
+ if address_type.lower() == "billing":
quotation.customer_address = address_name
quotation.address_display = address_display
-
+ quotation.shipping_address_name == quotation.shipping_address_name or address_name
+ elif address_type.lower() == "shipping":
+ quotation.shipping_address_name = address_name
+ quotation.shipping_address = address_display
+ quotation.customer_address == quotation.customer_address or address_name
apply_cart_settings(quotation=quotation)
diff --git a/erpnext/stock/dashboard/item_dashboard.js b/erpnext/stock/dashboard/item_dashboard.js
index 1bfa2cf..9bd03d4 100644
--- a/erpnext/stock/dashboard/item_dashboard.js
+++ b/erpnext/stock/dashboard/item_dashboard.js
@@ -108,8 +108,8 @@
if (context.data.length > 0) {
$(frappe.render_template('item_dashboard_list', context)).appendTo(this.result);
} else {
- var message = __(" Currently no stock available in any warehouse")
- $("<span class='text-muted small'>"+message+"</span>").appendTo(this.result);
+ var message = __("Currently no stock available in any warehouse");
+ $(`<span class='text-muted small'> ${message} </span>`).appendTo(this.result);
}
},
get_item_dashboard_data: function(data, max_count, show_item) {
diff --git a/erpnext/stock/desk_page/stock/stock.json b/erpnext/stock/desk_page/stock/stock.json
index 779e61f..38475a6 100644
--- a/erpnext/stock/desk_page/stock/stock.json
+++ b/erpnext/stock/desk_page/stock/stock.json
@@ -1,40 +1,44 @@
{
"cards": [
{
- "links": "[\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Stock Entry\",\n \"name\": \"Stock Entry\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"label\": \"Delivery Note\",\n \"name\": \"Delivery Note\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"label\": \"Purchase Receipt\",\n \"name\": \"Purchase Receipt\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Material Request\",\n \"name\": \"Material Request\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Pick List\",\n \"name\": \"Pick List\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Delivery Trip\",\n \"name\": \"Delivery Trip\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Stock Transactions"
+ "hidden": 0,
+ "label": "Stock Transactions",
+ "links": "[\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Stock Entry\",\n \"name\": \"Stock Entry\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Customer\"\n ],\n \"label\": \"Delivery Note\",\n \"name\": \"Delivery Note\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"label\": \"Purchase Receipt\",\n \"name\": \"Purchase Receipt\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Material Request\",\n \"name\": \"Material Request\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Pick List\",\n \"name\": \"Pick List\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Delivery Trip\",\n \"name\": \"Delivery Trip\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Stock Ledger Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock Ledger\",\n \"name\": \"Stock Ledger\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Stock Ledger Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock Balance\",\n \"name\": \"Stock Balance\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Stock Projected Qty\",\n \"name\": \"Stock Projected Qty\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Stock Summary\",\n \"name\": \"stock-balance\",\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Stock Ageing\",\n \"name\": \"Stock Ageing\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Item Price Stock\",\n \"name\": \"Item Price Stock\",\n \"type\": \"report\"\n }\n]",
- "title": "Stock Reports"
+ "hidden": 0,
+ "label": "Stock Reports",
+ "links": "[\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Stock Ledger Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock Ledger\",\n \"name\": \"Stock Ledger\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Stock Ledger Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock Balance\",\n \"name\": \"Stock Balance\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Stock Projected Qty\",\n \"name\": \"Stock Projected Qty\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Stock Summary\",\n \"name\": \"stock-balance\",\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Stock Ageing\",\n \"name\": \"Stock Ageing\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Item Price Stock\",\n \"name\": \"Item Price Stock\",\n \"type\": \"report\"\n }\n]"
},
{
- "icon": "fa fa-cog",
- "links": "[\n {\n \"label\": \"Stock Settings\",\n \"name\": \"Stock Settings\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Warehouse\",\n \"name\": \"Warehouse\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Unit of Measure (UOM)\",\n \"name\": \"UOM\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Brand\",\n \"name\": \"Brand\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Attribute\",\n \"name\": \"Item Attribute\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Variant Settings\",\n \"name\": \"Item Variant Settings\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Settings"
+ "hidden": 0,
+ "label": "Settings",
+ "links": "[\n {\n \"label\": \"Stock Settings\",\n \"name\": \"Stock Settings\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Warehouse\",\n \"name\": \"Warehouse\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Unit of Measure (UOM)\",\n \"name\": \"UOM\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Brand\",\n \"name\": \"Brand\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Attribute\",\n \"name\": \"Item Attribute\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Variant Settings\",\n \"name\": \"Item Variant Settings\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Item\",\n \"name\": \"Item\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Product Bundle\",\n \"name\": \"Product Bundle\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Item Group\",\n \"link\": \"Tree/Item Group\",\n \"name\": \"Item Group\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Price List\",\n \"name\": \"Price List\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Price\",\n \"name\": \"Item Price\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Shipping Rule\",\n \"name\": \"Shipping Rule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Pricing Rule\",\n \"name\": \"Pricing Rule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Alternative\",\n \"name\": \"Item Alternative\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Manufacturer\",\n \"name\": \"Item Manufacturer\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Variant Settings\",\n \"name\": \"Item Variant Settings\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Items and Pricing"
+ "hidden": 0,
+ "label": "Items and Pricing",
+ "links": "[\n {\n \"label\": \"Item\",\n \"name\": \"Item\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Product Bundle\",\n \"name\": \"Product Bundle\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Item Group\",\n \"link\": \"Tree/Item Group\",\n \"name\": \"Item Group\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Price List\",\n \"name\": \"Price List\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Price\",\n \"name\": \"Item Price\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Shipping Rule\",\n \"name\": \"Shipping Rule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Pricing Rule\",\n \"name\": \"Pricing Rule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Alternative\",\n \"name\": \"Item Alternative\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Manufacturer\",\n \"name\": \"Item Manufacturer\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Variant Settings\",\n \"name\": \"Item Variant Settings\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Serial No\",\n \"name\": \"Serial No\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Batch\",\n \"name\": \"Batch\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Installation Note\",\n \"name\": \"Installation Note\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Serial No\"\n ],\n \"doctype\": \"Serial No\",\n \"label\": \"Serial No Service Contract Expiry\",\n \"name\": \"Serial No Service Contract Expiry\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Serial No\"\n ],\n \"doctype\": \"Serial No\",\n \"label\": \"Serial No Status\",\n \"name\": \"Serial No Status\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Serial No\"\n ],\n \"doctype\": \"Serial No\",\n \"label\": \"Serial No Warranty Expiry\",\n \"name\": \"Serial No Warranty Expiry\",\n \"type\": \"report\"\n }\n]",
- "title": "Serial No and Batch"
+ "hidden": 0,
+ "label": "Serial No and Batch",
+ "links": "[\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Serial No\",\n \"name\": \"Serial No\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Batch\",\n \"name\": \"Batch\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Installation Note\",\n \"name\": \"Installation Note\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Serial No\"\n ],\n \"doctype\": \"Serial No\",\n \"label\": \"Serial No Service Contract Expiry\",\n \"name\": \"Serial No Service Contract Expiry\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Serial No\"\n ],\n \"doctype\": \"Serial No\",\n \"label\": \"Serial No Status\",\n \"name\": \"Serial No Status\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Serial No\"\n ],\n \"doctype\": \"Serial No\",\n \"label\": \"Serial No Warranty Expiry\",\n \"name\": \"Serial No Warranty Expiry\",\n \"type\": \"report\"\n }\n]"
},
{
- "icon": "fa fa-wrench",
- "links": "[\n {\n \"label\": \"Stock Reconciliation\",\n \"name\": \"Stock Reconciliation\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Landed Cost Voucher\",\n \"name\": \"Landed Cost Voucher\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Packing Slip\",\n \"name\": \"Packing Slip\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Quality Inspection\",\n \"name\": \"Quality Inspection\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Quality Inspection Template\",\n \"name\": \"Quality Inspection Template\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Quick Stock Balance\",\n \"name\": \"Quick Stock Balance\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Tools"
+ "hidden": 0,
+ "label": "Tools",
+ "links": "[\n {\n \"label\": \"Stock Reconciliation\",\n \"name\": \"Stock Reconciliation\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Landed Cost Voucher\",\n \"name\": \"Landed Cost Voucher\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Packing Slip\",\n \"name\": \"Packing Slip\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Quality Inspection\",\n \"name\": \"Quality Inspection\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Quality Inspection Template\",\n \"name\": \"Quality Inspection Template\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Quick Stock Balance\",\n \"name\": \"Quick Stock Balance\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-table",
- "links": "[\n {\n \"dependencies\": [\n \"Item Price\"\n ],\n \"doctype\": \"Item Price\",\n \"is_query_report\": false,\n \"label\": \"Item-wise Price List Rate\",\n \"name\": \"Item-wise Price List Rate\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Stock Entry\"\n ],\n \"doctype\": \"Stock Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock Analytics\",\n \"name\": \"Stock Analytics\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Delivery Note\"\n ],\n \"doctype\": \"Delivery Note\",\n \"is_query_report\": true,\n \"label\": \"Delivery Note Trends\",\n \"name\": \"Delivery Note Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Receipt\"\n ],\n \"doctype\": \"Purchase Receipt\",\n \"is_query_report\": true,\n \"label\": \"Purchase Receipt Trends\",\n \"name\": \"Purchase Receipt Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Delivery Note\"\n ],\n \"doctype\": \"Delivery Note\",\n \"is_query_report\": true,\n \"label\": \"Ordered Items To Be Delivered\",\n \"name\": \"Ordered Items To Be Delivered\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Receipt\"\n ],\n \"doctype\": \"Purchase Receipt\",\n \"is_query_report\": true,\n \"label\": \"Purchase Order Items To Be Received\",\n \"name\": \"Purchase Order Items To Be Received\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Bin\"\n ],\n \"doctype\": \"Bin\",\n \"is_query_report\": true,\n \"label\": \"Item Shortage Report\",\n \"name\": \"Item Shortage Report\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Batch\"\n ],\n \"doctype\": \"Batch\",\n \"is_query_report\": true,\n \"label\": \"Batch-Wise Balance History\",\n \"name\": \"Batch-Wise Balance History\",\n \"type\": \"report\"\n }\n]",
- "title": "Key Reports"
+ "hidden": 0,
+ "label": "Key Reports",
+ "links": "[\n {\n \"dependencies\": [\n \"Item Price\"\n ],\n \"doctype\": \"Item Price\",\n \"is_query_report\": false,\n \"label\": \"Item-wise Price List Rate\",\n \"name\": \"Item-wise Price List Rate\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Stock Entry\"\n ],\n \"doctype\": \"Stock Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock Analytics\",\n \"name\": \"Stock Analytics\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Delivery Note\"\n ],\n \"doctype\": \"Delivery Note\",\n \"is_query_report\": true,\n \"label\": \"Delivery Note Trends\",\n \"name\": \"Delivery Note Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Receipt\"\n ],\n \"doctype\": \"Purchase Receipt\",\n \"is_query_report\": true,\n \"label\": \"Purchase Receipt Trends\",\n \"name\": \"Purchase Receipt Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Delivery Note\"\n ],\n \"doctype\": \"Delivery Note\",\n \"is_query_report\": true,\n \"label\": \"Ordered Items To Be Delivered\",\n \"name\": \"Ordered Items To Be Delivered\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Receipt\"\n ],\n \"doctype\": \"Purchase Receipt\",\n \"is_query_report\": true,\n \"label\": \"Purchase Order Items To Be Received\",\n \"name\": \"Purchase Order Items To Be Received\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Bin\"\n ],\n \"doctype\": \"Bin\",\n \"is_query_report\": true,\n \"label\": \"Item Shortage Report\",\n \"name\": \"Item Shortage Report\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Batch\"\n ],\n \"doctype\": \"Batch\",\n \"is_query_report\": true,\n \"label\": \"Batch-Wise Balance History\",\n \"name\": \"Batch-Wise Balance History\",\n \"type\": \"report\"\n }\n]"
},
{
- "icon": "fa fa-list",
- "links": "[\n {\n \"dependencies\": [\n \"Material Request\"\n ],\n \"doctype\": \"Material Request\",\n \"is_query_report\": true,\n \"label\": \"Requested Items To Be Transferred\",\n \"name\": \"Requested Items To Be Transferred\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Stock Ledger Entry\"\n ],\n \"doctype\": \"Stock Ledger Entry\",\n \"is_query_report\": true,\n \"label\": \"Batch Item Expiry Status\",\n \"name\": \"Batch Item Expiry Status\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Price List\"\n ],\n \"doctype\": \"Price List\",\n \"is_query_report\": true,\n \"label\": \"Item Prices\",\n \"name\": \"Item Prices\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Itemwise Recommended Reorder Level\",\n \"name\": \"Itemwise Recommended Reorder Level\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Item Variant Details\",\n \"name\": \"Item Variant Details\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Order\"\n ],\n \"doctype\": \"Purchase Order\",\n \"is_query_report\": true,\n \"label\": \"Subcontracted Raw Materials To Be Transferred\",\n \"name\": \"Subcontracted Raw Materials To Be Transferred\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Order\"\n ],\n \"doctype\": \"Purchase Order\",\n \"is_query_report\": true,\n \"label\": \"Subcontracted Item To Be Received\",\n \"name\": \"Subcontracted Item To Be Received\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Stock Ledger Entry\"\n ],\n \"doctype\": \"Stock Ledger Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock and Account Value Comparison\",\n \"name\": \"Stock and Account Value Comparison\",\n \"type\": \"report\"\n }\n]",
- "title": "Other Reports"
+ "hidden": 0,
+ "label": "Other Reports",
+ "links": "[\n {\n \"dependencies\": [\n \"Material Request\"\n ],\n \"doctype\": \"Material Request\",\n \"is_query_report\": true,\n \"label\": \"Requested Items To Be Transferred\",\n \"name\": \"Requested Items To Be Transferred\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Stock Ledger Entry\"\n ],\n \"doctype\": \"Stock Ledger Entry\",\n \"is_query_report\": true,\n \"label\": \"Batch Item Expiry Status\",\n \"name\": \"Batch Item Expiry Status\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Price List\"\n ],\n \"doctype\": \"Price List\",\n \"is_query_report\": true,\n \"label\": \"Item Prices\",\n \"name\": \"Item Prices\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Itemwise Recommended Reorder Level\",\n \"name\": \"Itemwise Recommended Reorder Level\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Item Variant Details\",\n \"name\": \"Item Variant Details\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Order\"\n ],\n \"doctype\": \"Purchase Order\",\n \"is_query_report\": true,\n \"label\": \"Subcontracted Raw Materials To Be Transferred\",\n \"name\": \"Subcontracted Raw Materials To Be Transferred\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Order\"\n ],\n \"doctype\": \"Purchase Order\",\n \"is_query_report\": true,\n \"label\": \"Subcontracted Item To Be Received\",\n \"name\": \"Subcontracted Item To Be Received\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Stock Ledger Entry\"\n ],\n \"doctype\": \"Stock Ledger Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock and Account Value Comparison\",\n \"name\": \"Stock and Account Value Comparison\",\n \"type\": \"report\"\n }\n]"
}
],
"category": "Modules",
@@ -49,7 +53,7 @@
"idx": 0,
"is_standard": 1,
"label": "Stock",
- "modified": "2020-03-12 16:30:39.881667",
+ "modified": "2020-04-01 11:28:51.148421",
"modified_by": "Administrator",
"module": "Stock",
"name": "Stock",
@@ -58,27 +62,27 @@
"pin_to_top": 0,
"shortcuts": [
{
- "is_query_report": 0,
+ "label": "Item",
"link_to": "Item",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Pricing Rule",
"link_to": "Pricing Rule",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Stock Entry",
"link_to": "Stock Entry",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Stock Ledger",
"link_to": "Stock Ledger",
"type": "Report"
},
{
- "is_query_report": 0,
+ "label": "Stock Balance",
"link_to": "Stock Balance",
"type": "Report"
}
diff --git a/erpnext/stock/doctype/batch/batch.json b/erpnext/stock/doctype/batch/batch.json
index e6d4e9d..1eb4577 100644
--- a/erpnext/stock/doctype/batch/batch.json
+++ b/erpnext/stock/doctype/batch/batch.json
@@ -1,554 +1,194 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
"allow_import": 1,
- "allow_rename": 0,
"autoname": "field:batch_id",
- "beta": 0,
"creation": "2013-03-05 14:50:38",
- "custom": 0,
- "docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
- "editable_grid": 0,
"engine": "InnoDB",
+ "field_order": [
+ "sb_disabled",
+ "disabled",
+ "sb_batch",
+ "batch_id",
+ "item",
+ "item_name",
+ "image",
+ "parent_batch",
+ "manufacturing_date",
+ "column_break_3",
+ "batch_qty",
+ "stock_uom",
+ "expiry_date",
+ "source",
+ "supplier",
+ "column_break_9",
+ "reference_doctype",
+ "reference_name",
+ "section_break_7",
+ "description"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
+ "default": "0",
+ "fieldname": "disabled",
+ "fieldtype": "Check",
+ "label": "Disabled"
+ },
+ {
"depends_on": "eval:doc.__islocal",
"fieldname": "batch_id",
"fieldtype": "Data",
- "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": "Batch ID",
- "length": 0,
"no_copy": 1,
"oldfieldname": "batch_id",
"oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
"reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
"unique": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "item",
"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": 1,
"label": "Item",
- "length": 0,
- "no_copy": 0,
"oldfieldname": "item",
"oldfieldtype": "Link",
"options": "Item",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "reqd": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "image",
"fieldtype": "Attach Image",
"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": "image",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "image"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"depends_on": "eval:doc.parent_batch",
"fieldname": "parent_batch",
"fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Parent Batch",
- "length": 0,
- "no_copy": 0,
"options": "Batch",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "read_only": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_3",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "disabled",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Disabled",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"default": "Today",
"fieldname": "manufacturing_date",
"fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Manufacturing Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Manufacturing Date"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
+ "fieldname": "column_break_3",
+ "fieldtype": "Column Break"
+ },
+ {
"fieldname": "expiry_date",
"fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Expiry Date",
- "length": 0,
- "no_copy": 0,
"oldfieldname": "expiry_date",
- "oldfieldtype": "Date",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "oldfieldtype": "Date"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "source",
"fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Source",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "label": "Source"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "supplier",
"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": "Supplier",
- "length": 0,
- "no_copy": 0,
"options": "Supplier",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "read_only": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "column_break_9",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "fieldtype": "Column Break"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "reference_doctype",
"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": "Source Document Type",
- "length": 0,
- "no_copy": 0,
"options": "DocType",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "read_only": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "reference_name",
"fieldtype": "Dynamic Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Source Document Name",
- "length": 0,
- "no_copy": 0,
"options": "reference_doctype",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "read_only": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "section_break_7",
- "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,
- "translatable": 0,
- "unique": 0
+ "fieldtype": "Section Break"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "description",
"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": "Batch Description",
- "length": 0,
- "no_copy": 0,
"oldfieldname": "description",
"oldfieldtype": "Small Text",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
"width": "300px"
+ },
+ {
+ "fieldname": "sb_disabled",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "sb_batch",
+ "fieldtype": "Section Break",
+ "label": "Batch Details"
+ },
+ {
+ "fetch_from": "item.item_name",
+ "fieldname": "item_name",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Item Name",
+ "read_only": 1
+ },
+ {
+ "fieldname": "batch_qty",
+ "fieldtype": "Float",
+ "in_list_view": 1,
+ "label": "Batch Quantity",
+ "read_only": 1
+ },
+ {
+ "fetch_from": "item.stock_uom",
+ "fieldname": "stock_uom",
+ "fieldtype": "Link",
+ "label": "Batch UOM",
+ "options": "UOM",
+ "read_only": 1
}
],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
"icon": "fa fa-archive",
"idx": 1,
"image_field": "image",
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
"max_attachments": 5,
- "modified": "2018-08-29 06:28:57.985997",
+ "modified": "2019-10-03 22:38:45.104056",
"modified_by": "Administrator",
"module": "Stock",
"name": "Batch",
"owner": "harshada@webnotestech.com",
"permissions": [
{
- "amend": 0,
- "cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
- "if_owner": 0,
"import": 1,
- "permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Item Manager",
"set_user_permissions": 1,
"share": 1,
- "submit": 0,
"write": 1
}
],
"quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
+ "sort_field": "modified",
"sort_order": "DESC",
- "title_field": "item",
- "track_changes": 0,
- "track_seen": 0,
- "track_views": 0
+ "title_field": "batch_id"
}
\ No newline at end of file
diff --git a/erpnext/stock/doctype/batch/batch_dashboard.py b/erpnext/stock/doctype/batch/batch_dashboard.py
new file mode 100644
index 0000000..eb6a97e
--- /dev/null
+++ b/erpnext/stock/doctype/batch/batch_dashboard.py
@@ -0,0 +1,27 @@
+from __future__ import unicode_literals
+
+from frappe import _
+
+
+def get_data():
+ return {
+ 'fieldname': 'batch_no',
+ 'transactions': [
+ {
+ 'label': _('Buy'),
+ 'items': ['Purchase Invoice', 'Purchase Receipt']
+ },
+ {
+ 'label': _('Sell'),
+ 'items': ['Sales Invoice', 'Delivery Note']
+ },
+ {
+ 'label': _('Move'),
+ 'items': ['Stock Entry']
+ },
+ {
+ 'label': _('Quality'),
+ 'items': ['Quality Inspection']
+ }
+ ]
+ }
diff --git a/erpnext/stock/doctype/batch/batch_list.js b/erpnext/stock/doctype/batch/batch_list.js
index 7ee81aa..d4f74c3 100644
--- a/erpnext/stock/doctype/batch/batch_list.js
+++ b/erpnext/stock/doctype/batch/batch_list.js
@@ -1,12 +1,14 @@
frappe.listview_settings['Batch'] = {
- add_fields: ["item", "expiry_date"],
- get_indicator: function(doc) {
- if(doc.expiry_date && frappe.datetime.get_diff(doc.expiry_date, frappe.datetime.nowdate()) <= 0) {
- return [__("Expired"), "red", "expiry_date,>=,Today"]
- } else if(doc.expiry_date) {
- return [__("Not Expired"), "green", "expiry_date,<,Today"]
+ add_fields: ["item", "expiry_date", "batch_qty", "disabled"],
+ get_indicator: (doc) => {
+ if (doc.disabled) {
+ return [__("Disabled"), "darkgrey", "disabled,=,1"];
+ } else if (!doc.batch_qty) {
+ return [__("Empty"), "darkgrey", "batch_qty,=,0|disabled,=,0"];
+ } else if (doc.expiry_date && frappe.datetime.get_diff(doc.expiry_date, frappe.datetime.nowdate()) <= 0) {
+ return [__("Expired"), "red", "expiry_date,not in,|expiry_date,<=,Today|batch_qty,>,0|disabled,=,0"]
} else {
- return ["Not Set", "darkgrey", ""];
- }
+ return [__("Active"), "green", "batch_qty,>,0|disabled,=,0"];
+ };
}
};
diff --git a/erpnext/stock/doctype/batch/test_batch.py b/erpnext/stock/doctype/batch/test_batch.py
index 32445a6..1fce504 100644
--- a/erpnext/stock/doctype/batch/test_batch.py
+++ b/erpnext/stock/doctype/batch/test_batch.py
@@ -7,7 +7,7 @@
import unittest
from erpnext.stock.doctype.batch.batch import get_batch_qty, UnableToSelectBatchError, get_batch_no
-from frappe.utils import cint
+from frappe.utils import cint, flt
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
class TestBatch(unittest.TestCase):
@@ -35,12 +35,13 @@
receipt = frappe.get_doc(dict(
doctype='Purchase Receipt',
supplier='_Test Supplier',
+ company='_Test Company',
items=[
dict(
item_code='ITEM-BATCH-1',
qty=batch_qty,
rate=10,
- warehouse= 'Stores - WP'
+ warehouse= 'Stores - _TC'
)
]
)).insert()
@@ -175,6 +176,18 @@
self.assertEqual(get_batch_qty('batch a', '_Test Warehouse - _TC'), 90)
+ def test_total_batch_qty(self):
+ self.make_batch_item('ITEM-BATCH-3')
+ existing_batch_qty = flt(frappe.db.get_value("Batch", "B100", "batch_qty"))
+ stock_entry = self.make_new_batch_and_entry('ITEM-BATCH-3', 'B100', '_Test Warehouse - _TC')
+
+ current_batch_qty = flt(frappe.db.get_value("Batch", "B100", "batch_qty"))
+ self.assertEqual(current_batch_qty, existing_batch_qty + 90)
+
+ stock_entry.cancel()
+ current_batch_qty = flt(frappe.db.get_value("Batch", "B100", "batch_qty"))
+ self.assertEqual(current_batch_qty, existing_batch_qty)
+
@classmethod
def make_new_batch_and_entry(cls, item_name, batch_name, warehouse):
'''Make a new stock entry for given target warehouse and batch name of item'''
@@ -208,6 +221,8 @@
stock_entry.insert()
stock_entry.submit()
+ return stock_entry
+
def test_batch_name_with_naming_series(self):
stock_settings = frappe.get_single('Stock Settings')
use_naming_series = cint(stock_settings.use_naming_series)
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 30d82ca..dc96e7b 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -112,7 +112,6 @@
self.so_required()
self.validate_proj_cust()
self.check_sales_order_on_hold_or_close("against_sales_order")
- self.validate_for_items()
self.validate_warehouse()
self.validate_uom_is_integer("stock_uom", "stock_qty")
self.validate_uom_is_integer("uom", "qty")
@@ -166,12 +165,6 @@
if not res:
frappe.throw(_("Customer {0} does not belong to project {1}").format(self.customer, self.project))
- def validate_for_items(self):
- for d in self.get('items'):
- #Customer Provided parts will have zero valuation rate
- if frappe.db.get_value('Item', d.item_code, 'is_customer_provided_item'):
- d.allow_zero_valuation_rate = 1
-
def validate_warehouse(self):
super(DeliveryNote, self).validate_warehouse()
diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
index dc92c5c..47a72b2 100644
--- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
@@ -21,6 +21,7 @@
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order, create_dn_against_so
from erpnext.accounts.doctype.account.test_account import get_inventory_account, create_account
from erpnext.stock.doctype.warehouse.test_warehouse import get_warehouse
+from erpnext.stock.doctype.item.test_item import create_item
class TestDeliveryNote(unittest.TestCase):
def setUp(self):
@@ -433,6 +434,15 @@
update_delivery_note_status(dn.name, "Closed")
self.assertEqual(frappe.db.get_value("Delivery Note", dn.name, "Status"), "Closed")
+ def test_customer_provided_parts_dn(self):
+ create_item('CUST-0987', is_customer_provided_item = 1, customer = '_Test Customer', is_purchase_item = 0)
+ dn = create_delivery_note(item_code='CUST-0987', rate=0)
+ self.assertEqual(dn.get("items")[0].allow_zero_valuation_rate, 1)
+
+ # test if Delivery Note with rate is allowed against Customer Provided Item
+ dn2 = create_delivery_note(item_code='CUST-0987', do_not_save=True)
+ self.assertRaises(frappe.ValidationError, dn2.save)
+
def test_dn_billing_status_case1(self):
# SO -> DN -> SI
so = make_sales_order()
@@ -671,7 +681,7 @@
"item_code": args.item or args.item_code or "_Test Item",
"warehouse": args.warehouse or "_Test Warehouse - _TC",
"qty": args.qty or 1,
- "rate": args.rate or 100,
+ "rate": args.rate if args.get("rate") is not None else 100,
"conversion_factor": 1.0,
"allow_zero_valuation_rate": args.allow_zero_valuation_rate or 1,
"expense_account": args.expense_account or "Cost of Goods Sold - _TC",
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index e2e84c4..c62b3ab 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -101,6 +101,7 @@
self.add_default_uom_in_conversion_factor_table()
self.validate_conversion_factor()
self.validate_item_type()
+ self.validate_naming_series()
self.check_for_active_boms()
self.fill_customer_code()
self.check_item_tax()
@@ -186,7 +187,7 @@
or frappe.db.get_single_value('Stock Settings', 'default_warehouse'))
if default_warehouse:
warehouse_company = frappe.db.get_value("Warehouse", default_warehouse, "company")
-
+
if not default_warehouse or warehouse_company != default.company:
default_warehouse = frappe.db.get_value('Warehouse',
{'warehouse_name': _('Stores'), 'company': default.company})
@@ -307,7 +308,7 @@
if self.retain_sample and not frappe.db.get_single_value('Stock Settings', 'sample_retention_warehouse'):
frappe.throw(_("Please select Sample Retention Warehouse in Stock Settings first"))
if self.retain_sample and not self.has_batch_no:
- frappe.throw(_(" {0} Retain Sample is based on batch, please check Has Batch No to retain sample of item").format(
+ frappe.throw(_("{0} Retain Sample is based on batch, please check Has Batch No to retain sample of item").format(
self.item_code))
def get_context(self, context):
@@ -522,6 +523,13 @@
if self.has_serial_no == 0 and self.serial_no_series:
self.serial_no_series = None
+ def validate_naming_series(self):
+ for field in ["serial_no_series", "batch_number_series"]:
+ series = self.get(field)
+ if series and "#" in series and "." not in series:
+ frappe.throw(_("Invalid naming series (. missing) for {0}")
+ .format(frappe.bold(self.meta.get_field(field).label)))
+
def check_for_active_boms(self):
if self.default_bom:
bom_item = frappe.db.get_value("BOM", self.default_bom, "item")
@@ -1007,8 +1015,6 @@
order by pr.posting_date desc, pr.posting_time desc, pr.name desc
limit 1""", (item_code, cstr(doc_name)), as_dict=1)
-
-
purchase_order_date = getdate(last_purchase_order and last_purchase_order[0].transaction_date
or "1900-01-01")
purchase_receipt_date = getdate(last_purchase_receipt and
@@ -1016,7 +1022,7 @@
if last_purchase_order and (purchase_order_date >= purchase_receipt_date or not last_purchase_receipt):
# use purchase order
-
+
last_purchase = last_purchase_order[0]
purchase_date = purchase_order_date
@@ -1036,7 +1042,7 @@
"discount_percentage": flt(last_purchase.discount_percentage),
"purchase_date": purchase_date
})
-
+
conversion_rate = flt(conversion_rate) or 1.0
out.update({
diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js
index 6b26d38..6110ea8 100644
--- a/erpnext/stock/doctype/material_request/material_request.js
+++ b/erpnext/stock/doctype/material_request/material_request.js
@@ -19,11 +19,6 @@
frm.set_indicator_formatter('item_code',
function(doc) { return (doc.qty<=doc.ordered_qty) ? "green" : "orange"; });
- frm.set_query("item_code", "items", function() {
- return {
- query: "erpnext.controllers.queries.item_query"
- };
- });
},
onload: function(frm) {
@@ -145,7 +140,8 @@
},
get_item_data: function(frm, item) {
- if (!item.item_code) return;
+ if (item && !item.item_code) { return; }
+
frm.call({
method: "erpnext.stock.get_item_details.get_item_details",
child: item,
@@ -360,6 +356,22 @@
set_schedule_date(this.frm);
},
+ onload: function(doc, cdt, cdn) {
+ this.frm.set_query("item_code", "items", function() {
+ if (doc.material_request_type == "Customer Provided") {
+ return{
+ query: "erpnext.controllers.queries.item_query",
+ filters:{ 'customer': me.frm.doc.customer }
+ }
+ } else if (doc.material_request_type != "Manufacture") {
+ return{
+ query: "erpnext.controllers.queries.item_query",
+ filters: {'is_purchase_item': 1}
+ }
+ }
+ });
+ },
+
items_add: function(doc, cdt, cdn) {
var row = frappe.get_doc(cdt, cdn);
if(doc.schedule_date) {
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index 285643d..5b242a5 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -454,6 +454,9 @@
else:
target.s_warehouse = obj.warehouse
+ if source_parent.material_request_type == "Customer Provided":
+ target.allow_zero_valuation_rate = 1
+
def set_missing_values(source, target):
target.purpose = source.material_request_type
if source.job_card:
@@ -471,7 +474,7 @@
"doctype": "Stock Entry",
"validation": {
"docstatus": ["=", 1],
- "material_request_type": ["in", ["Material Transfer", "Material Issue"]]
+ "material_request_type": ["in", ["Material Transfer", "Material Issue", "Customer Provided"]]
}
},
"Material Request Item": {
diff --git a/erpnext/stock/doctype/material_request/test_material_request.py b/erpnext/stock/doctype/material_request/test_material_request.py
index 79cdc1a..b925aed 100644
--- a/erpnext/stock/doctype/material_request/test_material_request.py
+++ b/erpnext/stock/doctype/material_request/test_material_request.py
@@ -276,8 +276,8 @@
current_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC")
current_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC")
- self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 + 54.0)
- self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 + 3.0)
+ self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 - 54.0)
+ self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 - 3.0)
from erpnext.stock.doctype.material_request.material_request import make_stock_entry
@@ -331,8 +331,8 @@
current_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC")
current_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC")
- self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 + 27.0)
- self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 + 1.5)
+ self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 - 27.0)
+ self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 - 1.5)
# check if per complete is as expected for Stock Entry cancelled
se.cancel()
@@ -344,8 +344,8 @@
current_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC")
current_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC")
- self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 + 54.0)
- self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 + 3.0)
+ self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 - 54.0)
+ self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 - 3.0)
def test_completed_qty_for_over_transfer(self):
existing_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC")
@@ -425,8 +425,8 @@
current_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC")
current_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC")
- self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 + 54.0)
- self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 + 3.0)
+ self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 - 54.0)
+ self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 - 3.0)
def test_incorrect_mapping_of_stock_entry(self):
# submit material request of type Transfer
@@ -512,7 +512,7 @@
mr.submit()
#testing bin value after material request is submitted
- self.assertEqual(_get_requested_qty(), existing_requested_qty + 54.0)
+ self.assertEqual(_get_requested_qty(), existing_requested_qty - 54.0)
# receive items to allow issue
self._insert_stock_entry(60, 6, "_Test Warehouse - _TC")
@@ -609,6 +609,8 @@
def test_customer_provided_parts_mr(self):
from erpnext.stock.doctype.material_request.material_request import make_stock_entry
create_item('CUST-0987', is_customer_provided_item = 1, customer = '_Test Customer', is_purchase_item = 0)
+ existing_requested_qty = self._get_requested_qty("_Test Customer", "_Test Warehouse - _TC")
+
mr = make_material_request(item_code='CUST-0987', material_request_type='Customer Provided')
se = make_stock_entry(mr.name)
se.insert()
@@ -617,7 +619,10 @@
self.assertEqual(se.get("items")[0].material_request, mr.name)
mr = frappe.get_doc("Material Request", mr.name)
mr.submit()
+ current_requested_qty = self._get_requested_qty("_Test Customer", "_Test Warehouse - _TC")
+
self.assertEqual(mr.per_ordered, 100)
+ self.assertEqual(existing_requested_qty, current_requested_qty)
def make_material_request(**args):
args = frappe._dict(args)
diff --git a/erpnext/stock/doctype/pick_list/pick_list.js b/erpnext/stock/doctype/pick_list/pick_list.js
index 2789711..d46b98b 100644
--- a/erpnext/stock/doctype/pick_list/pick_list.js
+++ b/erpnext/stock/doctype/pick_list/pick_list.js
@@ -38,13 +38,17 @@
};
});
},
- get_item_locations: (frm) => {
- if (!frm.doc.locations || !frm.doc.locations.length) {
- frappe.msgprint(__('First add items in the Item Locations table'));
+ set_item_locations:(frm, save) => {
+ if (!(frm.doc.locations && frm.doc.locations.length)) {
+ frappe.msgprint(__('Add items in the Item Locations table'));
} else {
- frm.call('set_item_locations');
+ frm.call('set_item_locations', {save: save});
}
},
+ get_item_locations: (frm) => {
+ // Button on the form
+ frm.events.set_item_locations(frm, false);
+ },
refresh: (frm) => {
frm.trigger('add_get_items_button');
if (frm.doc.docstatus === 1) {
@@ -52,8 +56,13 @@
'pick_list_name': frm.doc.name,
'purpose': frm.doc.purpose
}).then(target_document_exists => {
+ frm.set_df_property("locations", "allow_on_submit", target_document_exists ? 0 : 1);
+
if (target_document_exists) return;
- if (frm.doc.purpose === 'Delivery against Sales Order') {
+
+ frm.add_custom_button(__('Update Current Stock'), () => frm.trigger('update_pick_list_stock'));
+
+ if (frm.doc.purpose === 'Delivery') {
frm.add_custom_button(__('Delivery Note'), () => frm.trigger('create_delivery_note'), __('Create'));
} else {
frm.add_custom_button(__('Stock Entry'), () => frm.trigger('create_stock_entry'), __('Create'));
@@ -105,6 +114,7 @@
method: 'erpnext.stock.doctype.pick_list.pick_list.create_delivery_note',
frm: frm
});
+
},
create_stock_entry: (frm) => {
frappe.xcall('erpnext.stock.doctype.pick_list.pick_list.create_stock_entry', {
@@ -114,9 +124,12 @@
frappe.set_route("Form", 'Stock Entry', stock_entry.name);
});
},
+ update_pick_list_stock: (frm) => {
+ frm.events.set_item_locations(frm, true);
+ },
add_get_items_button: (frm) => {
let purpose = frm.doc.purpose;
- if (purpose != 'Delivery against Sales Order' || frm.doc.docstatus !== 0) return;
+ if (purpose != 'Delivery' || frm.doc.docstatus !== 0) return;
let get_query_filters = {
docstatus: 1,
per_delivered: ['<', 100],
diff --git a/erpnext/stock/doctype/pick_list/pick_list.json b/erpnext/stock/doctype/pick_list/pick_list.json
index 8d5ef3d..c01388d 100644
--- a/erpnext/stock/doctype/pick_list/pick_list.json
+++ b/erpnext/stock/doctype/pick_list/pick_list.json
@@ -1,4 +1,5 @@
{
+ "actions": [],
"autoname": "naming_series:",
"creation": "2019-07-11 16:03:13.681045",
"doctype": "DocType",
@@ -44,7 +45,7 @@
"options": "Warehouse"
},
{
- "depends_on": "eval:doc.purpose==='Delivery against Sales Order'",
+ "depends_on": "eval:doc.purpose==='Delivery'",
"fieldname": "customer",
"fieldtype": "Link",
"in_list_view": 1,
@@ -59,6 +60,7 @@
"options": "Work Order"
},
{
+ "allow_on_submit": 1,
"fieldname": "locations",
"fieldtype": "Table",
"label": "Item Locations",
@@ -86,7 +88,7 @@
"fieldname": "purpose",
"fieldtype": "Select",
"label": "Purpose",
- "options": "Material Transfer for Manufacture\nMaterial Transfer\nDelivery against Sales Order"
+ "options": "Material Transfer for Manufacture\nMaterial Transfer\nDelivery"
},
{
"depends_on": "eval:['Material Transfer', 'Material Issue'].includes(doc.purpose)",
@@ -111,7 +113,8 @@
}
],
"is_submittable": 1,
- "modified": "2019-08-29 21:10:11.572387",
+ "links": [],
+ "modified": "2020-03-17 11:38:41.932875",
"modified_by": "Administrator",
"module": "Stock",
"name": "Pick List",
diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py
index c4d8c41..616de5e 100644
--- a/erpnext/stock/doctype/pick_list/pick_list.py
+++ b/erpnext/stock/doctype/pick_list/pick_list.py
@@ -29,7 +29,7 @@
frappe.throw(_('For item {0} at row {1}, count of serial numbers does not match with the picked quantity')
.format(frappe.bold(item.item_code), frappe.bold(item.idx)))
- def set_item_locations(self):
+ def set_item_locations(self, save=False):
items = self.aggregate_item_qty()
self.item_location_map = frappe._dict()
@@ -43,7 +43,7 @@
item_code = item_doc.item_code
self.item_location_map.setdefault(item_code,
- get_available_item_locations(item_code, from_warehouses, self.item_count_map.get(item_code)))
+ get_available_item_locations(item_code, from_warehouses, self.item_count_map.get(item_code), self.company))
locations = get_items_with_location_and_quantity(item_doc, self.item_location_map)
@@ -59,12 +59,17 @@
location.update(row)
self.append('locations', location)
+ if save:
+ self.save()
+
def aggregate_item_qty(self):
locations = self.get('locations')
self.item_count_map = {}
# aggregate qty for same item
item_map = OrderedDict()
for item in locations:
+ if not item.item_code:
+ frappe.throw("Row #{0}: Item Code is Mandatory".format(item.idx))
item_code = item.item_code
reference = item.sales_order_item or item.material_request_item
key = (item_code, item.uom, reference)
@@ -85,6 +90,10 @@
return item_map.values()
+def validate_item_locations(pick_list):
+ if not pick_list.locations:
+ frappe.throw(_("Add items in the Item Locations table"))
+
def get_items_with_location_and_quantity(item_doc, item_location_map):
available_locations = item_location_map.get(item_doc.item_code)
locations = []
@@ -130,14 +139,14 @@
item_location_map[item_doc.item_code] = available_locations
return locations
-def get_available_item_locations(item_code, from_warehouses, required_qty):
+def get_available_item_locations(item_code, from_warehouses, required_qty, company):
locations = []
if frappe.get_cached_value('Item', item_code, 'has_serial_no'):
- locations = get_available_item_locations_for_serialized_item(item_code, from_warehouses, required_qty)
+ locations = get_available_item_locations_for_serialized_item(item_code, from_warehouses, required_qty, company)
elif frappe.get_cached_value('Item', item_code, 'has_batch_no'):
- locations = get_available_item_locations_for_batched_item(item_code, from_warehouses, required_qty)
+ locations = get_available_item_locations_for_batched_item(item_code, from_warehouses, required_qty, company)
else:
- locations = get_available_item_locations_for_other_item(item_code, from_warehouses, required_qty)
+ locations = get_available_item_locations_for_other_item(item_code, from_warehouses, required_qty, company)
total_qty_available = sum(location.get('qty') for location in locations)
@@ -150,9 +159,10 @@
return locations
-def get_available_item_locations_for_serialized_item(item_code, from_warehouses, required_qty):
+def get_available_item_locations_for_serialized_item(item_code, from_warehouses, required_qty, company):
filters = frappe._dict({
'item_code': item_code,
+ 'company': company,
'warehouse': ['!=', '']
})
@@ -180,7 +190,7 @@
return locations
-def get_available_item_locations_for_batched_item(item_code, from_warehouses, required_qty):
+def get_available_item_locations_for_batched_item(item_code, from_warehouses, required_qty, company):
warehouse_condition = 'and warehouse in %(warehouses)s' if from_warehouses else ''
batch_locations = frappe.db.sql("""
SELECT
@@ -192,6 +202,7 @@
WHERE
sle.batch_no = batch.name
and sle.`item_code`=%(item_code)s
+ and sle.`company` = %(company)s
and IFNULL(batch.`expiry_date`, '2200-01-01') > %(today)s
{warehouse_condition}
GROUP BY
@@ -202,16 +213,20 @@
ORDER BY IFNULL(batch.`expiry_date`, '2200-01-01'), batch.`creation`
""".format(warehouse_condition=warehouse_condition), { #nosec
'item_code': item_code,
+ 'company': company,
'today': today(),
'warehouses': from_warehouses
}, as_dict=1)
return batch_locations
-def get_available_item_locations_for_other_item(item_code, from_warehouses, required_qty):
+def get_available_item_locations_for_other_item(item_code, from_warehouses, required_qty, company):
# gets all items available in different warehouses
+ warehouses = [x.get('name') for x in frappe.get_list("Warehouse", {'company': company}, "name")]
+
filters = frappe._dict({
'item_code': item_code,
+ 'warehouse': ['in', warehouses],
'actual_qty': ['>', 0]
})
@@ -230,7 +245,9 @@
@frappe.whitelist()
def create_delivery_note(source_name, target_doc=None):
pick_list = frappe.get_doc('Pick List', source_name)
- sales_orders = [d.sales_order for d in pick_list.locations]
+ validate_item_locations(pick_list)
+
+ sales_orders = [d.sales_order for d in pick_list.locations if d.sales_order]
sales_orders = set(sales_orders)
delivery_note = None
@@ -238,6 +255,10 @@
delivery_note = create_delivery_note_from_sales_order(sales_order,
delivery_note, skip_item_mapping=True)
+ # map rows without sales orders as well
+ if not delivery_note:
+ delivery_note = frappe.new_doc("Delivery Note")
+
item_table_mapper = {
'doctype': 'Delivery Note Item',
'field_map': {
@@ -248,9 +269,25 @@
'condition': lambda doc: abs(doc.delivered_qty) < abs(doc.qty) and doc.delivered_by_supplier!=1
}
+ item_table_mapper_without_so = {
+ 'doctype': 'Delivery Note Item',
+ 'field_map': {
+ 'rate': 'rate',
+ 'name': 'name',
+ 'parent': '',
+ }
+ }
+
for location in pick_list.locations:
- sales_order_item = frappe.get_cached_doc('Sales Order Item', location.sales_order_item)
- dn_item = map_child_doc(sales_order_item, delivery_note, item_table_mapper)
+ if location.sales_order_item:
+ sales_order_item = frappe.get_cached_doc('Sales Order Item', {'name':location.sales_order_item})
+ else:
+ sales_order_item = None
+
+ source_doc, table_mapper = [sales_order_item, item_table_mapper] if sales_order_item \
+ else [location, item_table_mapper_without_so]
+
+ dn_item = map_child_doc(source_doc, delivery_note, table_mapper)
if dn_item:
dn_item.warehouse = location.warehouse
@@ -258,7 +295,7 @@
dn_item.batch_no = location.batch_no
dn_item.serial_no = location.serial_no
- update_delivery_note_item(sales_order_item, dn_item, delivery_note)
+ update_delivery_note_item(source_doc, dn_item, delivery_note)
set_delivery_note_missing_values(delivery_note)
@@ -269,6 +306,7 @@
@frappe.whitelist()
def create_stock_entry(pick_list):
pick_list = frappe.get_doc(json.loads(pick_list))
+ validate_item_locations(pick_list)
if stock_entry_exists(pick_list.get('name')):
return frappe.msgprint(_('Stock Entry has been already created against this Pick List'))
@@ -318,7 +356,7 @@
@frappe.whitelist()
def target_document_exists(pick_list_name, purpose):
- if purpose == 'Delivery against Sales Order':
+ if purpose == 'Delivery':
return frappe.db.exists('Delivery Note', {
'pick_list': pick_list_name
})
diff --git a/erpnext/stock/doctype/pick_list_item/pick_list_item.json b/erpnext/stock/doctype/pick_list_item/pick_list_item.json
index c7a35df..71fbf9a 100644
--- a/erpnext/stock/doctype/pick_list_item/pick_list_item.json
+++ b/erpnext/stock/doctype/pick_list_item/pick_list_item.json
@@ -1,4 +1,5 @@
{
+ "actions": [],
"creation": "2019-07-11 16:01:22.832885",
"doctype": "DocType",
"editable_grid": 1,
@@ -8,6 +9,7 @@
"item_name",
"column_break_2",
"description",
+ "item_group",
"section_break_5",
"warehouse",
"quantity_section",
@@ -120,7 +122,8 @@
"fieldtype": "Link",
"in_list_view": 1,
"label": "Item",
- "options": "Item"
+ "options": "Item",
+ "reqd": 1
},
{
"fieldname": "quantity_section",
@@ -166,10 +169,18 @@
"fieldtype": "Data",
"label": "Material Request Item",
"read_only": 1
+ },
+ {
+ "fetch_from": "item_code.item_group",
+ "fieldname": "item_group",
+ "fieldtype": "Data",
+ "label": "Item Group",
+ "read_only": 1
}
],
"istable": 1,
- "modified": "2019-08-29 21:28:39.539007",
+ "links": [],
+ "modified": "2020-03-13 19:08:21.995986",
"modified_by": "Administrator",
"module": "Stock",
"name": "Pick List Item",
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
index 35446ec..e38bb38 100755
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
@@ -47,6 +47,7 @@
"is_subcontracted",
"supplier_warehouse",
"items_section",
+ "scan_barcode",
"items",
"pricing_rule_details",
"pricing_rules",
@@ -1070,13 +1071,18 @@
"label": "Inter Company Reference",
"options": "Delivery Note",
"read_only": 1
+ },
+ {
+ "fieldname": "scan_barcode",
+ "fieldtype": "Data",
+ "label": "Scan Barcode"
}
],
"icon": "fa fa-truck",
"idx": 261,
"is_submittable": 1,
"links": [],
- "modified": "2019-12-30 19:12:49.709711",
+ "modified": "2020-04-06 16:31:37.444891",
"modified_by": "Administrator",
"module": "Stock",
"name": "Purchase Receipt",
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index cba7f20..113da9f 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -375,6 +375,33 @@
location = frappe.db.get_value('Asset', assets[0].name, 'location')
self.assertEquals(location, "Test Location")
+
+ def test_purchase_return_with_submitted_asset(self):
+ from erpnext.stock.doctype.purchase_receipt.purchase_receipt import make_purchase_return
+
+ pr = make_purchase_receipt(item_code="Test Asset Item", qty=1)
+
+ asset = frappe.get_doc("Asset", {
+ 'purchase_receipt': pr.name
+ })
+ asset.available_for_use_date = frappe.utils.nowdate()
+ asset.gross_purchase_amount = 50.0
+ asset.append("finance_books", {
+ "expected_value_after_useful_life": 10,
+ "depreciation_method": "Straight Line",
+ "total_number_of_depreciations": 3,
+ "frequency_of_depreciation": 1,
+ "depreciation_start_date": frappe.utils.nowdate()
+ })
+ asset.submit()
+
+ pr_return = make_purchase_return(pr.name)
+ self.assertRaises(frappe.exceptions.ValidationError, pr_return.submit)
+
+ asset.load_from_db()
+ asset.cancel()
+
+ pr_return.submit()
def test_purchase_receipt_for_enable_allow_cost_center_in_entry_of_bs_account(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
diff --git a/erpnext/stock/doctype/serial_no/serial_no.json b/erpnext/stock/doctype/serial_no/serial_no.json
index fb28b5c..731a730 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.json
+++ b/erpnext/stock/doctype/serial_no/serial_no.json
@@ -1,4 +1,5 @@
{
+ "actions": [],
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:serial_no",
@@ -41,7 +42,6 @@
"delivery_document_no",
"delivery_date",
"delivery_time",
- "is_cancelled",
"column_break5",
"customer",
"customer_name",
@@ -56,7 +56,8 @@
"warranty_period",
"more_info",
"serial_no_details",
- "company"
+ "company",
+ "status"
],
"fields": [
{
@@ -307,16 +308,6 @@
"read_only": 1
},
{
- "fieldname": "is_cancelled",
- "fieldtype": "Select",
- "hidden": 1,
- "label": "Is Cancelled",
- "oldfieldname": "is_cancelled",
- "oldfieldtype": "Select",
- "options": "\nYes\nNo",
- "report_hide": 1
- },
- {
"fieldname": "column_break5",
"fieldtype": "Column Break",
"width": "50%"
@@ -423,11 +414,20 @@
"remember_last_selected_value": 1,
"reqd": 1,
"search_index": 1
+ },
+ {
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "in_standard_filter": 1,
+ "label": "Status",
+ "options": "\nActive\nDelivered\nExpired",
+ "read_only": 1
}
],
"icon": "fa fa-barcode",
"idx": 1,
- "modified": "2020-02-28 19:31:09.357323",
+ "links": [],
+ "modified": "2020-04-08 13:29:58.517772",
"modified_by": "Administrator",
"module": "Stock",
"name": "Serial No",
diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py
index 772ac58..b32c709 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.py
+++ b/erpnext/stock/doctype/serial_no/serial_no.py
@@ -35,6 +35,15 @@
self.set_maintenance_status()
self.validate_warehouse()
self.validate_item()
+ self.set_status()
+
+ def set_status(self):
+ if self.delivery_document_type:
+ self.status = "Delivered"
+ elif self.warranty_expiry_date and getdate(self.warranty_expiry_date) <= getdate(nowdate()):
+ self.status = "Expired"
+ else:
+ self.status = "Active"
def set_maintenance_status(self):
if not self.warranty_expiry_date and not self.amc_expiry_date:
@@ -197,6 +206,7 @@
self.set_purchase_details(last_sle.get("purchase_sle"))
self.set_sales_details(last_sle.get("delivery_sle"))
self.set_maintenance_status()
+ self.set_status()
def process_serial_no(sle):
item_det = get_item_details(sle.item_code)
diff --git a/erpnext/stock/doctype/serial_no/serial_no_list.js b/erpnext/stock/doctype/serial_no/serial_no_list.js
index 5b1e312..651f790 100644
--- a/erpnext/stock/doctype/serial_no/serial_no_list.js
+++ b/erpnext/stock/doctype/serial_no/serial_no_list.js
@@ -1,14 +1,12 @@
frappe.listview_settings['Serial No'] = {
- add_fields: ["is_cancelled", "item_code", "warehouse", "warranty_expiry_date", "delivery_document_type"],
+ add_fields: ["item_code", "warehouse", "warranty_expiry_date", "delivery_document_type"],
get_indicator: (doc) => {
- if (doc.is_cancelled) {
- return [__("Cancelled"), "red", "is_cancelled,=,Yes"];
- } else if (doc.delivery_document_type) {
- return [__("Delivered"), "green", "delivery_document_type,is,set|is_cancelled,=,No"];
+ if (doc.delivery_document_type) {
+ return [__("Delivered"), "green", "delivery_document_type,is,set"];
} else if (doc.warranty_expiry_date && frappe.datetime.get_diff(doc.warranty_expiry_date, frappe.datetime.nowdate()) <= 0) {
- return [__("Expired"), "red", "warranty_expiry_date,not in,|warranty_expiry_date,<=,Today|delivery_document_type,is,not set|is_cancelled,=,No"];
+ return [__("Expired"), "red", "warranty_expiry_date,not in,|warranty_expiry_date,<=,Today|delivery_document_type,is,not set"];
} else {
- return [__("Active"), "green", "delivery_document_type,is,not set|is_cancelled,=,No"];
+ return [__("Active"), "green", "delivery_document_type,is,not set"];
}
}
};
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index be4c78b..7cf822b 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -50,6 +50,7 @@
self.validate_posting_time()
self.validate_purpose()
self.validate_item()
+ self.validate_customer_provided_item()
self.validate_qty()
self.set_transfer_qty()
self.validate_uom_is_integer("uom", "qty")
@@ -203,10 +204,6 @@
frappe.throw(_("Row #{0}: Please specify Serial No for Item {1}").format(item.idx, item.item_code),
frappe.MandatoryError)
- #Customer Provided parts will have zero valuation rate
- if frappe.db.get_value('Item', item.item_code, 'is_customer_provided_item'):
- item.allow_zero_valuation_rate = 1
-
def validate_qty(self):
manufacture_purpose = ["Manufacture", "Material Consumption for Manufacture"]
diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
index ee5f237..2afabe1 100644
--- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
@@ -744,7 +744,7 @@
def test_customer_provided_parts_se(self):
create_item('CUST-0987', is_customer_provided_item = 1, customer = '_Test Customer', is_purchase_item = 0)
- se = make_stock_entry(item_code='CUST-0987', purporse = 'Material Receipt', qty=4, to_warehouse = "_Test Warehouse - _TC")
+ se = make_stock_entry(item_code='CUST-0987', purpose = 'Material Receipt', qty=4, to_warehouse = "_Test Warehouse - _TC")
self.assertEqual(se.get("items")[0].allow_zero_valuation_rate, 1)
self.assertEqual(se.get("items")[0].amount, 0)
diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
index 5fe89d6..dab5a7b 100644
--- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
+++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
@@ -37,11 +37,19 @@
def on_submit(self):
self.check_stock_frozen_date()
self.actual_amt_check()
+ self.calculate_batch_qty()
if not self.get("via_landed_cost_voucher"):
from erpnext.stock.doctype.serial_no.serial_no import process_serial_no
process_serial_no(self)
+ def calculate_batch_qty(self):
+ if self.batch_no:
+ batch_qty = frappe.db.get_value("Stock Ledger Entry",
+ {"docstatus": 1, "batch_no": self.batch_no, "is_cancelled": "No"},
+ "sum(actual_qty)") or 0
+ frappe.db.set_value("Batch", self.batch_no, "batch_qty", batch_qty)
+
#check for item quantity available in stock
def actual_amt_check(self):
if self.batch_no and not self.get("allow_negative_stock"):
@@ -64,7 +72,7 @@
frappe.throw(_("Actual Qty is mandatory"))
def validate_item(self):
- item_det = frappe.db.sql("""select name, has_batch_no, docstatus,
+ item_det = frappe.db.sql("""select name, item_name, has_batch_no, docstatus,
is_stock_item, has_variants, stock_uom, create_new_batch
from tabItem where name=%s""", self.item_code, as_dict=True)
@@ -79,10 +87,11 @@
# check if batch number is required
if self.voucher_type != 'Stock Reconciliation':
if item_det.has_batch_no ==1:
+ batch_item = self.item_code if self.item_code == item_det.item_name else self.item_code + ":" + item_det.item_name
if not self.batch_no:
- frappe.throw(_("Batch number is mandatory for Item {0}").format(self.item_code))
+ frappe.throw(_("Batch number is mandatory for Item {0}").format(batch_item))
elif not frappe.db.get_value("Batch",{"item": self.item_code, "name": self.batch_no}):
- frappe.throw(_("{0} is not a valid Batch Number for Item {1}").format(self.batch_no, self.item_code))
+ frappe.throw(_("{0} is not a valid Batch Number for Item {1}").format(self.batch_no, batch_item))
elif item_det.has_batch_no ==0 and self.batch_no and self.is_cancelled == "No":
frappe.throw(_("The Item {0} cannot have Batch").format(self.item_code))
@@ -139,4 +148,3 @@
frappe.db.add_index("Stock Ledger Entry", ["voucher_no", "voucher_type"])
frappe.db.add_index("Stock Ledger Entry", ["batch_no", "item_code", "warehouse"])
-
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index afa2394..0a49c26 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -488,12 +488,14 @@
["has_serial_no", "has_batch_no"], as_dict=1)
serial_nos = ""
- if item_dict.get("has_serial_no"):
- qty, rate, serial_nos = get_qty_rate_for_serial_nos(item_code,
- warehouse, posting_date, posting_time, item_dict)
+ with_serial_no = True if item_dict.get("has_serial_no") else False
+ data = get_stock_balance(item_code, warehouse, posting_date, posting_time,
+ with_valuation_rate=with_valuation_rate, with_serial_no=with_serial_no)
+
+ if with_serial_no:
+ qty, rate, serial_nos = data
else:
- qty, rate = get_stock_balance(item_code, warehouse,
- posting_date, posting_time, with_valuation_rate=with_valuation_rate)
+ qty, rate = data
if item_dict.get("has_batch_no"):
qty = get_batch_qty(batch_no, warehouse) or 0
@@ -504,28 +506,6 @@
'serial_nos': serial_nos
}
-def get_qty_rate_for_serial_nos(item_code, warehouse, posting_date, posting_time, item_dict):
- args = {
- "item_code": item_code,
- "warehouse": warehouse,
- "posting_date": posting_date,
- "posting_time": posting_time,
- }
-
- serial_nos_list = [serial_no.get("name")
- for serial_no in get_available_serial_nos(args)]
-
- qty = len(serial_nos_list)
- serial_nos = '\n'.join(serial_nos_list)
- args.update({
- 'qty': qty,
- "serial_nos": serial_nos
- })
-
- rate = get_incoming_rate(args, raise_error_if_no_rate=False) or 0
-
- return qty, rate, serial_nos
-
@frappe.whitelist()
def get_difference_account(purpose, company):
if purpose == 'Stock Reconciliation':
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index 9c5a8e1..b1bfc90 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -245,7 +245,7 @@
'item_group_defaults': item_group_defaults,
'brand_defaults': brand_defaults
})
-
+
warehouse = get_item_warehouse(item, args, overwrite_warehouse, defaults)
if args.get('doctype') == "Material Request" and not args.get('material_request_type'):
@@ -279,7 +279,7 @@
"cost_center": get_default_cost_center(args, item_defaults, item_group_defaults, brand_defaults),
'has_serial_no': item.has_serial_no,
'has_batch_no': item.has_batch_no,
- "batch_no": None,
+ "batch_no": args.get("batch_no"),
"uom": args.uom,
"min_order_qty": flt(item.min_order_qty) if args.doctype == "Material Request" else "",
"qty": flt(args.qty) or 1.0,
@@ -377,7 +377,7 @@
else:
warehouse = args.get('warehouse')
-
+
return warehouse
def update_barcode_value(out):
diff --git a/erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py b/erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py
index 94ec314..1af68dd 100644
--- a/erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py
+++ b/erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py
@@ -35,7 +35,7 @@
gl_data = voucher_wise_gl_data.get(key) or {}
d.account_value = gl_data.get("account_value", 0)
d.difference_value = (d.stock_value - d.account_value)
- if abs(d.difference_value) > 1.0/10 ** currency_precision:
+ if abs(d.difference_value) > 0.1:
data.append(d)
return data
diff --git a/erpnext/stock/stock_balance.py b/erpnext/stock/stock_balance.py
index e5dc6b1..2bdb04e 100644
--- a/erpnext/stock/stock_balance.py
+++ b/erpnext/stock/stock_balance.py
@@ -113,13 +113,24 @@
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) * mr_item.conversion_factor)
+ inward_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.material_request_type in ('Purchase', 'Manufacture')
+ and mr_item.qty > mr_item.ordered_qty and mr_item.parent=mr.name
+ and mr.status!='Stopped' and mr.docstatus=1""", (item_code, warehouse))
+
+ outward_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.material_request_type in ('Material Issue', 'Material Transfer')
and mr_item.qty > mr_item.ordered_qty and mr_item.parent=mr.name
and mr.status!='Stopped' and mr.docstatus=1""", (item_code, warehouse))
- return flt(indented_qty[0][0]) if indented_qty else 0
+ inward_qty, outward_qty = flt(inward_qty[0][0]) if inward_qty else 0, flt(outward_qty[0][0]) if outward_qty else 0
+ indented_qty = inward_qty - outward_qty
+
+ return indented_qty
def get_ordered_qty(item_code, warehouse):
ordered_qty = frappe.db.sql("""
@@ -145,9 +156,9 @@
from erpnext.stock.utils import get_bin
bin = get_bin(item_code, warehouse)
mismatch = False
- for fld, val in qty_dict.items():
- if flt(bin.get(fld)) != flt(val):
- bin.set(fld, flt(val))
+ for field, value in qty_dict.items():
+ if flt(bin.get(field)) != flt(value):
+ bin.set(field, flt(value))
mismatch = True
if mismatch:
diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py
index f3381c7..7f32b8d 100644
--- a/erpnext/stock/utils.py
+++ b/erpnext/stock/utils.py
@@ -74,7 +74,8 @@
return sum(sle_map.values())
@frappe.whitelist()
-def get_stock_balance(item_code, warehouse, posting_date=None, posting_time=None, with_valuation_rate=False):
+def get_stock_balance(item_code, warehouse, posting_date=None, posting_time=None,
+ with_valuation_rate=False, with_serial_no=False):
"""Returns stock balance quantity at given warehouse on given posting date or current date.
If `with_valuation_rate` is True, will return tuple (qty, rate)"""
@@ -84,17 +85,51 @@
if not posting_date: posting_date = nowdate()
if not posting_time: posting_time = nowtime()
- last_entry = get_previous_sle({
+ args = {
"item_code": item_code,
"warehouse":warehouse,
"posting_date": posting_date,
- "posting_time": posting_time })
+ "posting_time": posting_time
+ }
+
+ last_entry = get_previous_sle(args)
if with_valuation_rate:
- return (last_entry.qty_after_transaction, last_entry.valuation_rate) if last_entry else (0.0, 0.0)
+ if with_serial_no:
+ serial_nos = last_entry.get("serial_no")
+
+ if (serial_nos and
+ len(get_serial_nos_data(serial_nos)) < last_entry.qty_after_transaction):
+ serial_nos = get_serial_nos_data_after_transactions(args)
+
+ return ((last_entry.qty_after_transaction, last_entry.valuation_rate, serial_nos)
+ if last_entry else (0.0, 0.0, 0.0))
+ else:
+ return (last_entry.qty_after_transaction, last_entry.valuation_rate) if last_entry else (0.0, 0.0)
else:
return last_entry.qty_after_transaction if last_entry else 0.0
+def get_serial_nos_data_after_transactions(args):
+ serial_nos = []
+ data = frappe.db.sql(""" SELECT serial_no, actual_qty
+ FROM `tabStock Ledger Entry`
+ WHERE
+ item_code = %(item_code)s and warehouse = %(warehouse)s
+ and timestamp(posting_date, posting_time) < timestamp(%(posting_date)s, %(posting_time)s)
+ order by posting_date, posting_time asc """, args, as_dict=1)
+
+ for d in data:
+ if d.actual_qty > 0:
+ serial_nos.extend(get_serial_nos_data(d.serial_no))
+ else:
+ serial_nos = list(set(serial_nos) - set(get_serial_nos_data(d.serial_no)))
+
+ return '\n'.join(serial_nos)
+
+def get_serial_nos_data(serial_nos):
+ from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
+ return get_serial_nos(serial_nos)
+
@frappe.whitelist()
def get_latest_stock_qty(item_code, warehouse=None):
values, condition = [item_code], ""
diff --git a/erpnext/support/desk_page/support/support.json b/erpnext/support/desk_page/support/support.json
index 4a7885e..596987f 100644
--- a/erpnext/support/desk_page/support/support.json
+++ b/erpnext/support/desk_page/support/support.json
@@ -1,30 +1,34 @@
{
"cards": [
{
- "links": "[\n {\n \"description\": \"Service Level.\",\n \"label\": \"Service Level\",\n \"name\": \"Service Level\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Service Level Agreement.\",\n \"label\": \"Service Level Agreement\",\n \"name\": \"Service Level Agreement\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Service Level Agreement"
+ "hidden": 0,
+ "label": "Service Level Agreement",
+ "links": "[\n {\n \"description\": \"Service Level.\",\n \"label\": \"Service Level\",\n \"name\": \"Service Level\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Service Level Agreement.\",\n \"label\": \"Service Level Agreement\",\n \"name\": \"Service Level Agreement\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"label\": \"Maintenance Schedule\",\n \"name\": \"Maintenance Schedule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Maintenance Visit\",\n \"name\": \"Maintenance Visit\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Maintenance"
+ "hidden": 0,
+ "label": "Maintenance",
+ "links": "[\n {\n \"label\": \"Maintenance Schedule\",\n \"name\": \"Maintenance Schedule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Maintenance Visit\",\n \"name\": \"Maintenance Visit\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Support queries from customers.\",\n \"label\": \"Issue\",\n \"name\": \"Issue\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Issue Type.\",\n \"label\": \"Issue Type\",\n \"name\": \"Issue Type\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Issue Priority.\",\n \"label\": \"Issue Priority\",\n \"name\": \"Issue Priority\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Issues"
+ "hidden": 0,
+ "label": "Issues",
+ "links": "[\n {\n \"description\": \"Support queries from customers.\",\n \"label\": \"Issue\",\n \"name\": \"Issue\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Issue Type.\",\n \"label\": \"Issue Type\",\n \"name\": \"Issue Type\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Issue Priority.\",\n \"label\": \"Issue Priority\",\n \"name\": \"Issue Priority\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "links": "[\n {\n \"description\": \"Warranty Claim against Serial No.\",\n \"label\": \"Warranty Claim\",\n \"name\": \"Warranty Claim\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Single unit of an Item.\",\n \"label\": \"Serial No\",\n \"name\": \"Serial No\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Warranty"
+ "hidden": 0,
+ "label": "Warranty",
+ "links": "[\n {\n \"description\": \"Warranty Claim against Serial No.\",\n \"label\": \"Warranty Claim\",\n \"name\": \"Warranty Claim\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Single unit of an Item.\",\n \"label\": \"Serial No\",\n \"name\": \"Serial No\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-list",
- "links": "[\n {\n \"label\": \"Support Settings\",\n \"name\": \"Support Settings\",\n \"type\": \"doctype\"\n }\n]",
- "title": "Settings"
+ "hidden": 0,
+ "label": "Settings",
+ "links": "[\n {\n \"label\": \"Support Settings\",\n \"name\": \"Support Settings\",\n \"type\": \"doctype\"\n }\n]"
},
{
- "icon": "fa fa-list",
- "links": "[\n {\n \"dependencies\": [\n \"Issue\"\n ],\n \"doctype\": \"Issue\",\n \"is_query_report\": true,\n \"label\": \"Minutes to First Response for Issues\",\n \"name\": \"Minutes to First Response for Issues\",\n \"type\": \"report\"\n }\n]",
- "title": "Reports"
+ "hidden": 0,
+ "label": "Reports",
+ "links": "[\n {\n \"dependencies\": [\n \"Issue\"\n ],\n \"doctype\": \"Issue\",\n \"is_query_report\": true,\n \"label\": \"Minutes to First Response for Issues\",\n \"name\": \"Minutes to First Response for Issues\",\n \"type\": \"report\"\n }\n]"
}
],
"category": "Modules",
@@ -39,7 +43,7 @@
"idx": 0,
"is_standard": 1,
"label": "Support",
- "modified": "2020-03-12 16:30:39.482621",
+ "modified": "2020-04-01 11:28:51.120583",
"modified_by": "Administrator",
"module": "Support",
"name": "Support",
@@ -48,17 +52,17 @@
"pin_to_top": 0,
"shortcuts": [
{
- "is_query_report": 0,
+ "label": "Issue",
"link_to": "Issue",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Service Level",
"link_to": "Service Level",
"type": "DocType"
},
{
- "is_query_report": 0,
+ "label": "Maintenance Visit",
"link_to": "Maintenance Visit",
"type": "DocType"
}
diff --git a/erpnext/templates/includes/cart.js b/erpnext/templates/includes/cart.js
index 456bc7e..c6dfd35 100644
--- a/erpnext/templates/includes/cart.js
+++ b/erpnext/templates/includes/cart.js
@@ -26,15 +26,14 @@
bind_address_select: function() {
$(".cart-addresses").on('click', '.address-card', function(e) {
const $card = $(e.currentTarget);
- const address_fieldname = $card.closest('[data-fieldname]').attr('data-fieldname');
+ const address_type = $card.closest('[data-address-type]').attr('data-address-type');
const address_name = $card.closest('[data-address-name]').attr('data-address-name');
-
return frappe.call({
type: "POST",
method: "erpnext.shopping_cart.cart.update_cart_address",
freeze: true,
args: {
- address_fieldname,
+ address_type,
address_name
},
callback: function(r) {
diff --git a/erpnext/templates/includes/cart/cart_address.html b/erpnext/templates/includes/cart/cart_address.html
index f7f3548..60de3af 100644
--- a/erpnext/templates/includes/cart/cart_address.html
+++ b/erpnext/templates/includes/cart/cart_address.html
@@ -18,7 +18,7 @@
<h6 class="text-uppercase">{{ _("Shipping Address") }}</h6>
<div class="row no-gutters" data-fieldname="shipping_address_name">
{% for address in shipping_addresses %}
- <div class="mr-3 mb-3 w-25" data-address-name="{{address.name}}" {% if doc.shipping_address_name == address.name %} data-active {% endif %}>
+ <div class="mr-3 mb-3 w-25" data-address-name="{{address.name}}" data-address-type="shipping" {% if doc.shipping_address_name == address.name %} data-active {% endif %}>
{% include "templates/includes/cart/address_card.html" %}
</div>
{% endfor %}
@@ -28,7 +28,7 @@
<h6 class="text-uppercase">{{ _("Billing Address") }}</h6>
<div class="row no-gutters" data-fieldname="customer_address">
{% for address in billing_addresses %}
- <div class="mr-3 mb-3 w-25" data-address-name="{{address.name}}" {% if doc.customer_address == address.name %} data-active {% endif %}>
+ <div class="mr-3 mb-3 w-25" data-address-name="{{address.name}}" data-address-type="billing" {% if doc.customer_address == address.name %} data-active {% endif %}>
{% include "templates/includes/cart/address_card.html" %}
</div>
{% endfor %}
@@ -123,9 +123,19 @@
primary_action: (values) => {
frappe.call('erpnext.shopping_cart.cart.add_new_address', { doc: values })
.then(r => {
- d.hide();
- window.location.reload();
+ frappe.call({
+ method: "erpnext.shopping_cart.cart.update_cart_address",
+ args: {
+ address_type: r.message.address_type,
+ address_name: r.message.name
+ },
+ callback: function (r) {
+ d.hide();
+ window.location.reload();
+ }
+ });
});
+
}
})
diff --git a/erpnext/templates/includes/order/order_taxes.html b/erpnext/templates/includes/order/order_taxes.html
index 4a32aa4..ebec838 100644
--- a/erpnext/templates/includes/order/order_taxes.html
+++ b/erpnext/templates/includes/order/order_taxes.html
@@ -10,16 +10,16 @@
{% endif %}
{% for d in doc.taxes %}
-{% if d.base_tax_amount > 0 %}
-<tr>
- <td class="text-right" colspan="2">
- {{ d.description }}
- </td>
- <td class="text-right">
- {{ d.get_formatted("base_tax_amount") }}
- </td>
-</tr>
-{% endif %}
+ {% if d.base_tax_amount %}
+ <tr>
+ <td class="text-right" colspan="2">
+ {{ d.description }}
+ </td>
+ <td class="text-right">
+ {{ d.get_formatted("base_tax_amount") }}
+ </td>
+ </tr>
+ {% endif %}
{% endfor %}
{% if doc.doctype == 'Quotation' %}
diff --git a/erpnext/templates/pages/cart.html b/erpnext/templates/pages/cart.html
index 912702e..3033d15 100644
--- a/erpnext/templates/pages/cart.html
+++ b/erpnext/templates/pages/cart.html
@@ -12,16 +12,6 @@
{% block header_actions %}
-{% if doc.items and cart_settings.enable_checkout %}
-<button class="btn btn-primary btn-place-order" type="button">
- {{ _("Place Order") }}
-</button>
-{% endif %}
-{% if doc.items and not cart_settings.enable_checkout %}
-<button class="btn btn-primary btn-request-for-quotation" type="button">
- {{ _("Request for Quotation") }}
-</button>
-{% endif %}
{% endblock %}
{% block page_content %}
@@ -56,6 +46,20 @@
{% endif %}
{% if doc.items %}
+ <div class="place-order-container">
+ {% if cart_settings.enable_checkout %}
+ <button class="btn btn-primary btn-place-order" type="button">
+ {{ _("Place Order") }}
+ </button>
+ {% else %}
+ <button class="btn btn-primary btn-request-for-quotation" type="button">
+ {{ _("Request for Quotation") }}
+ </button>
+ {% endif %}
+ </div>
+ {% endif %}
+
+ {% if doc.items %}
{% if doc.tc_name %}
<div class="terms-and-conditions-link">
<a href class="link-terms-and-conditions" data-terms-name="{{ doc.tc_name }}">
diff --git a/yarn.lock b/yarn.lock
index 9b31518..c5509d6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1133,9 +1133,9 @@
brace-expansion "^1.1.7"
minimist@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
- integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
+ version "1.2.5"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
+ integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
ms@2.0.0:
version "2.0.0"