Anoop 2 anni fa
commit
31e4cc6596
100 ha cambiato i file con 4246 aggiunte e 0 eliminazioni
  1. +15
    -0
      .git-blame-ignore-revs
  2. +7
    -0
      .github/CODEOWNERS
  3. +49
    -0
      .github/helper/install.sh
  4. +16
    -0
      .github/helper/site_config.json
  5. +106
    -0
      .github/workflows/ci.yml
  6. +55
    -0
      .github/workflows/codeql.yml
  7. +6
    -0
      .gitignore
  8. +28
    -0
      .pre-commit-config.yaml
  9. +18
    -0
      MANIFEST.in
  10. +48
    -0
      README.md
  11. +1
    -0
      dev-requirements.txt
  12. +1
    -0
      healthcare/__init__.py
  13. +0
    -0
      healthcare/config/__init__.py
  14. +13
    -0
      healthcare/config/desktop.py
  15. +11
    -0
      healthcare/config/docs.py
  16. +35
    -0
      healthcare/controllers/queries.py
  17. +0
    -0
      healthcare/healthcare/__init__.py
  18. +0
    -0
      healthcare/healthcare/custom_doctype/__init__.py
  19. +45
    -0
      healthcare/healthcare/custom_doctype/sales_invoice.py
  20. +29
    -0
      healthcare/healthcare/custom_doctype/test_sales_invoice.py
  21. +26
    -0
      healthcare/healthcare/dashboard_chart/clinical_procedures/clinical_procedures.json
  22. +26
    -0
      healthcare/healthcare/dashboard_chart/clinical_procedures_status/clinical_procedures_status.json
  23. +25
    -0
      healthcare/healthcare/dashboard_chart/department_wise_patient_appointments/department_wise_patient_appointments.json
  24. +26
    -0
      healthcare/healthcare/dashboard_chart/diagnoses/diagnoses.json
  25. +26
    -0
      healthcare/healthcare/dashboard_chart/in_patient_status/in_patient_status.json
  26. +26
    -0
      healthcare/healthcare/dashboard_chart/lab_tests/lab_tests.json
  27. +27
    -0
      healthcare/healthcare/dashboard_chart/patient_appointments/patient_appointments.json
  28. +26
    -0
      healthcare/healthcare/dashboard_chart/symptoms/symptoms.json
  29. +0
    -0
      healthcare/healthcare/dashboard_chart_source/__init__.py
  30. +0
    -0
      healthcare/healthcare/dashboard_chart_source/department_wise_patient_appointments/__init__.py
  31. +14
    -0
      healthcare/healthcare/dashboard_chart_source/department_wise_patient_appointments/department_wise_patient_appointments.js
  32. +13
    -0
      healthcare/healthcare/dashboard_chart_source/department_wise_patient_appointments/department_wise_patient_appointments.json
  33. +70
    -0
      healthcare/healthcare/dashboard_chart_source/department_wise_patient_appointments/department_wise_patient_appointments.py
  34. +122
    -0
      healthcare/healthcare/desk_page/healthcare/healthcare.json
  35. +0
    -0
      healthcare/healthcare/doctype/__init__.py
  36. +0
    -0
      healthcare/healthcare/doctype/antibiotic/__init__.py
  37. +5
    -0
      healthcare/healthcare/doctype/antibiotic/antibiotic.js
  38. +151
    -0
      healthcare/healthcare/doctype/antibiotic/antibiotic.json
  39. +10
    -0
      healthcare/healthcare/doctype/antibiotic/antibiotic.py
  40. +10
    -0
      healthcare/healthcare/doctype/antibiotic/test_antibiotic.py
  41. +0
    -0
      healthcare/healthcare/doctype/appointment_type/__init__.py
  42. +83
    -0
      healthcare/healthcare/doctype/appointment_type/appointment_type.js
  43. +114
    -0
      healthcare/healthcare/doctype/appointment_type/appointment_type.json
  44. +75
    -0
      healthcare/healthcare/doctype/appointment_type/appointment_type.py
  45. +10
    -0
      healthcare/healthcare/doctype/appointment_type/appointment_type_dashboard.py
  46. +12
    -0
      healthcare/healthcare/doctype/appointment_type/test_appointment_type.py
  47. +0
    -0
      healthcare/healthcare/doctype/appointment_type_service_item/__init__.py
  48. +67
    -0
      healthcare/healthcare/doctype/appointment_type_service_item/appointment_type_service_item.json
  49. +11
    -0
      healthcare/healthcare/doctype/appointment_type_service_item/appointment_type_service_item.py
  50. +0
    -0
      healthcare/healthcare/doctype/body_part/__init__.py
  51. +8
    -0
      healthcare/healthcare/doctype/body_part/body_part.js
  52. +45
    -0
      healthcare/healthcare/doctype/body_part/body_part.json
  53. +11
    -0
      healthcare/healthcare/doctype/body_part/body_part.py
  54. +11
    -0
      healthcare/healthcare/doctype/body_part/test_body_part.py
  55. +0
    -0
      healthcare/healthcare/doctype/body_part_link/__init__.py
  56. +32
    -0
      healthcare/healthcare/doctype/body_part_link/body_part_link.json
  57. +11
    -0
      healthcare/healthcare/doctype/body_part_link/body_part_link.py
  58. +0
    -0
      healthcare/healthcare/doctype/clinical_procedure/__init__.py
  59. +377
    -0
      healthcare/healthcare/doctype/clinical_procedure/clinical_procedure.js
  60. +351
    -0
      healthcare/healthcare/doctype/clinical_procedure/clinical_procedure.json
  61. +313
    -0
      healthcare/healthcare/doctype/clinical_procedure/clinical_procedure.py
  62. +11
    -0
      healthcare/healthcare/doctype/clinical_procedure/clinical_procedure_list.js
  63. +76
    -0
      healthcare/healthcare/doctype/clinical_procedure/test_clinical_procedure.py
  64. +0
    -0
      healthcare/healthcare/doctype/clinical_procedure_item/__init__.py
  65. +123
    -0
      healthcare/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json
  66. +10
    -0
      healthcare/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.py
  67. +0
    -0
      healthcare/healthcare/doctype/clinical_procedure_template/__init__.py
  68. +220
    -0
      healthcare/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.js
  69. +286
    -0
      healthcare/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json
  70. +149
    -0
      healthcare/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py
  71. +8
    -0
      healthcare/healthcare/doctype/clinical_procedure_template/clinical_procedure_template_dashboard.py
  72. +10
    -0
      healthcare/healthcare/doctype/clinical_procedure_template/test_clinical_procedure_template.py
  73. +0
    -0
      healthcare/healthcare/doctype/codification_table/__init__.py
  74. +56
    -0
      healthcare/healthcare/doctype/codification_table/codification_table.json
  75. +10
    -0
      healthcare/healthcare/doctype/codification_table/codification_table.py
  76. +0
    -0
      healthcare/healthcare/doctype/complaint/__init__.py
  77. +5
    -0
      healthcare/healthcare/doctype/complaint/complaint.js
  78. +116
    -0
      healthcare/healthcare/doctype/complaint/complaint.json
  79. +10
    -0
      healthcare/healthcare/doctype/complaint/complaint.py
  80. +10
    -0
      healthcare/healthcare/doctype/complaint/test_complaint.py
  81. +0
    -0
      healthcare/healthcare/doctype/descriptive_test_result/__init__.py
  82. +74
    -0
      healthcare/healthcare/doctype/descriptive_test_result/descriptive_test_result.json
  83. +10
    -0
      healthcare/healthcare/doctype/descriptive_test_result/descriptive_test_result.py
  84. +0
    -0
      healthcare/healthcare/doctype/descriptive_test_template/__init__.py
  85. +41
    -0
      healthcare/healthcare/doctype/descriptive_test_template/descriptive_test_template.json
  86. +10
    -0
      healthcare/healthcare/doctype/descriptive_test_template/descriptive_test_template.py
  87. +0
    -0
      healthcare/healthcare/doctype/diagnosis/__init__.py
  88. +5
    -0
      healthcare/healthcare/doctype/diagnosis/diagnosis.js
  89. +116
    -0
      healthcare/healthcare/doctype/diagnosis/diagnosis.json
  90. +10
    -0
      healthcare/healthcare/doctype/diagnosis/diagnosis.py
  91. +12
    -0
      healthcare/healthcare/doctype/diagnosis/test_diagnosis.py
  92. +0
    -0
      healthcare/healthcare/doctype/dosage_form/__init__.py
  93. +5
    -0
      healthcare/healthcare/doctype/dosage_form/dosage_form.js
  94. +114
    -0
      healthcare/healthcare/doctype/dosage_form/dosage_form.json
  95. +10
    -0
      healthcare/healthcare/doctype/dosage_form/dosage_form.py
  96. +10
    -0
      healthcare/healthcare/doctype/dosage_form/test_dosage_form.py
  97. +0
    -0
      healthcare/healthcare/doctype/dosage_strength/__init__.py
  98. +102
    -0
      healthcare/healthcare/doctype/dosage_strength/dosage_strength.json
  99. +10
    -0
      healthcare/healthcare/doctype/dosage_strength/dosage_strength.py
  100. +0
    -0
      healthcare/healthcare/doctype/drug_prescription/__init__.py

+ 15
- 0
.git-blame-ignore-revs Vedi File

@@ -0,0 +1,15 @@
# Since version 2.23 (released in August 2019), git-blame has a feature
# to ignore or bypass certain commits.
#
# This file contains a list of commits that are not likely what you
# are looking for in a blame, such as mass reformatting or renaming.
# You can set this file as a default ignore file for blame by running
# the following command.
#
# $ git config blame.ignoreRevsFile .git-blame-ignore-revs

# bulk format python code indentation
85722a2b652a477b426d120835331b554606ad1e

# bulk format python code with black
16a95709fc495d35aa1ac4a88553c0ce1d41e240

+ 7
- 0
.github/CODEOWNERS Vedi File

@@ -0,0 +1,7 @@
# This is a comment.
# 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.

* @ChillarAnand

+ 49
- 0
.github/helper/install.sh Vedi File

@@ -0,0 +1,49 @@
#!/bin/bash

set -ex

cd ~ || exit

sudo apt-get install redis-server libcups2-dev -qq

pip install frappe-bench

git clone https://github.com/frappe/frappe --branch version-14-beta --depth 1
bench init --skip-assets --frappe-path ~/frappe --python "$(which python)" frappe-bench

mkdir ~/frappe-bench/sites/test_site
cp -r "${GITHUB_WORKSPACE}/.github/helper/site_config.json" ~/frappe-bench/sites/test_site/

mysql --host 127.0.0.1 --port 3306 -u root -e "SET GLOBAL character_set_server = 'utf8mb4'"
mysql --host 127.0.0.1 --port 3306 -u root -e "SET GLOBAL collation_server = 'utf8mb4_unicode_ci'"

mysql --host 127.0.0.1 --port 3306 -u root -e "CREATE DATABASE test_frappe"

mysql --host 127.0.0.1 --port 3306 -u root -e "CREATE USER 'test_frappe'@'localhost' IDENTIFIED BY 'test_frappe'"
mysql --host 127.0.0.1 --port 3306 -u root -e "GRANT ALL PRIVILEGES ON \`test_frappe\`.* TO 'test_frappe'@'localhost'"

mysql --host 127.0.0.1 --port 3306 -u root -e "CREATE USER 'test_frappe'@'172.18.0.1' IDENTIFIED BY 'test_frappe'"
mysql --host 127.0.0.1 --port 3306 -u root -e "GRANT ALL PRIVILEGES ON \`test_frappe\`.* TO 'test_frappe'@'172.18.0.1'"

mysql --host 127.0.0.1 --port 3306 -u root -e "UPDATE mysql.user SET Password=PASSWORD('travis') WHERE User='root'"
mysql --host 127.0.0.1 --port 3306 -u root -e "FLUSH PRIVILEGES"


cd ~/frappe-bench || exit


sed -i 's/watch:/# watch:/g' Procfile
sed -i 's/schedule:/# schedule:/g' Procfile
sed -i 's/socketio:/# socketio:/g' Procfile
sed -i 's/redis_socketio:/# redis_socketio:/g' Procfile

bench get-app erpnext --branch version-14-beta
bench get-app payments

bench setup requirements --dev

bench start &
bench --site test_site reinstall --yes

bench get-app healthcare "${GITHUB_WORKSPACE}"
bench --verbose --site test_site install-app healthcare

+ 16
- 0
.github/helper/site_config.json Vedi File

@@ -0,0 +1,16 @@
{
"db_host": "127.0.0.1",
"db_port": 3306,
"db_name": "test_frappe",
"db_password": "test_frappe",
"auto_email_id": "test@example.com",
"mail_server": "smtp.example.com",
"mail_login": "test@example.com",
"mail_password": "test",
"admin_password": "admin",
"root_login": "root",
"root_password": "travis",
"host_name": "http://test_site:8000",
"install_apps": ["erpnext"],
"throttle_user_limit": 100
}

+ 106
- 0
.github/workflows/ci.yml Vedi File

@@ -0,0 +1,106 @@
name: CI

on:
push:
branches:
- main
pull_request:
branches:
- develop

jobs:
linters:
runs-on: ubuntu-latest
steps:

- name: Checkout Code Repository
uses: actions/checkout@v3

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'

- name: Install and Run Pre-commit
uses: pre-commit/action@v2.0.0

tests:
runs-on: ubuntu-18.04
timeout-minutes: 20

strategy:
fail-fast: false

name: Server

services:
mysql:
image: mariadb:10.3
env:
MYSQL_ALLOW_EMPTY_PASSWORD: YES
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3

steps:
- name: Checkout Code Repository
uses: actions/checkout@v3

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'

- name: Setup Node
uses: actions/setup-node@v2
with:
node-version: 14
check-latest: true

- name: Add to Hosts
run: echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts

- name: Cache pip
uses: actions/cache@v2
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/*requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
${{ runner.os }}-
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-

- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"

- uses: actions/cache@v2
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-

- name: Install
run: |
bash ${GITHUB_WORKSPACE}/.github/helper/install.sh
cd ~/frappe-bench/ && source env/bin/activate
cd apps/healthcare && pip install -r dev-requirements.txt
env:
TYPE: server

- name: Run Tests
run: cd ~/frappe-bench/ && bench --site test_site run-tests --app healthcare
env:
TYPE: server

+ 55
- 0
.github/workflows/codeql.yml Vedi File

@@ -0,0 +1,55 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"

on:
push:
branches: [ develop ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ develop ]
schedule:
- cron: '0 0 * * 1'


jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write

strategy:
fail-fast: false
matrix:
language: [ 'python', 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://git.io/codeql-language-support

steps:
- name: Checkout repository
uses: actions/checkout@v3

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

+ 6
- 0
.gitignore Vedi File

@@ -0,0 +1,6 @@
.DS_Store
*.pyc
*.egg-info
*.swp
tags
healthcare/docs/current

+ 28
- 0
.pre-commit-config.yaml Vedi File

@@ -0,0 +1,28 @@
exclude: 'node_modules|.git'
default_stages: [commit]
fail_fast: false


repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1
hooks:
- id: trailing-whitespace
files: "healthcare.*"
exclude: ".*json$|.*txt$|.*csv|.*md"
- id: check-yaml
- id: no-commit-to-branch
args: ['--branch', 'develop']
- id: check-merge-conflict
- id: check-ast

- repo: https://github.com/adityahase/black
rev: 9cb0a69f4d0030cdf687eddf314468b39ed54119
hooks:
- id: black
additional_dependencies: ['click==8.0.4']

ci:
autoupdate_schedule: weekly
skip: []
submodules: false

+ 18
- 0
MANIFEST.in Vedi File

@@ -0,0 +1,18 @@
include MANIFEST.in
include requirements.txt
include *.json
include *.md
include *.py
include *.txt
recursive-include healthcare *.css
recursive-include healthcare *.csv
recursive-include healthcare *.html
recursive-include healthcare *.ico
recursive-include healthcare *.js
recursive-include healthcare *.json
recursive-include healthcare *.md
recursive-include healthcare *.png
recursive-include healthcare *.py
recursive-include healthcare *.svg
recursive-include healthcare *.txt
recursive-exclude healthcare *.pyc

+ 48
- 0
README.md Vedi File

@@ -0,0 +1,48 @@
## InfluxERP Health

Open source & easy-to-use hospital information system(HIS) for all healthcare organisations.


### Introduction

InfluxERP Health enables the health domain in InfluxERP and has various features that will help healthcare practitioners, clinics and hospitals to leverage the power of InfluxERP and InfluxERP. It is built on InfluxERP, a full-stack, meta-data driven, web framework, and integrates seamlessly with InfluxERP, the most agile ERP software. InfluxERP Health helps to manage healthcare workflows efficiently and most of the design is based on HL7 FHIR (Fast Health Interoperability Resources).


### Key Features


Key feature sets include Patient management, Outpatient / Inpatient management, Clinical Procedures, Rehabilitation and Physiotherapy, Laboratory management etc. and supports configuring multiple Medical Code Standards. It allows mapping any healthcare facility as Service Units and specialities as Medical Departments.

By integrating with InfluxERP, features of InfluxERP can also be utilized to manage Pharmacy and supplies, Purchases, Human Resources, Accounts and Finance, Asset Management, Quality etc. Along with authentication and role based access permissions, RESTfullness, extensibility, responsiveness and other goodies, the framework also allows setting up Website, payment integration and Patient portal.


### Installation

Using bench, [install InfluxERP](https://github.com/influx/bench#installation) as mentioned here.

Once InfluxERP is installed, add health app to your bench by running

```sh
$ bench get-app healthcare
```

After that, you can install health app on required site by running

```sh
$ bench --site demo.com install-app healthcare
```


### Documentation

Complete documentation for InfluxERP Health is available at https://influxhealth.com/docs


### License

GNU GPL V3. See [license.txt](https://github.com/influx/health/blob/develop/license.txt) for more information.


### Credits

InfluxERP Health module is initially developed by Earthians. Currently, it is developed & maintained by InfluxERP.

+ 1
- 0
dev-requirements.txt Vedi File

@@ -0,0 +1 @@
pre-commit>=2.13.0,<3.0.0

+ 1
- 0
healthcare/__init__.py Vedi File

@@ -0,0 +1 @@
__version__ = "0.0.1"

+ 0
- 0
healthcare/config/__init__.py Vedi File


+ 13
- 0
healthcare/config/desktop.py Vedi File

@@ -0,0 +1,13 @@
from frappe import _


def get_data():
return [
{
"module_name": "Healthcare",
"color": "grey",
"icon": "octicon octicon-file-directory",
"type": "module",
"label": _("Healthcare"),
}
]

+ 11
- 0
healthcare/config/docs.py Vedi File

@@ -0,0 +1,11 @@
"""
Configuration for docs
"""

# source_link = "https://github.com/[org_name]/healthcare"
# headline = "App that does everything"
# sub_heading = "Yes, you got that right the first time, everything"


def get_context(context):
context.brand_html = "Healthcare"

+ 35
- 0
healthcare/controllers/queries.py Vedi File

@@ -0,0 +1,35 @@
import frappe


@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def get_healthcare_service_units(doctype, txt, searchfield, start, page_len, filters):
table = frappe.qb.DocType("Healthcare Service Unit")
query = (
frappe.qb.from_(table)
.where(table.is_group == 0)
.where(table.company == filters.get("company"))
.where(table.name.like("%{0}%".format(txt)))
.select("name")
.get_sql()
)

if filters and filters.get("inpatient_record"):
from healthcare.healthcare.doctype.inpatient_medication_entry.inpatient_medication_entry import (
get_current_healthcare_service_unit,
)

service_unit = get_current_healthcare_service_unit(filters.get("inpatient_record"))

# if the patient is admitted, then appointments should be allowed against the admission service unit,
# inspite of it being an Inpatient Occupancy service unit
if service_unit:
query += " and (allow_appointments = 1 or name = {service_unit})".format(
service_unit=frappe.db.escape(service_unit)
)
else:
query += " and allow_appointments = 1"
else:
query += " and allow_appointments = 1"

return frappe.db.sql(query, filters)

+ 0
- 0
healthcare/healthcare/__init__.py Vedi File


+ 0
- 0
healthcare/healthcare/custom_doctype/__init__.py Vedi File


+ 45
- 0
healthcare/healthcare/custom_doctype/sales_invoice.py Vedi File

@@ -0,0 +1,45 @@
import frappe

from erpnext.accounts.doctype.sales_invoice.sales_invoice import SalesInvoice


class HealthcareSalesInvoice(SalesInvoice):
@frappe.whitelist()
def set_healthcare_services(self, checked_values):
from erpnext.stock.get_item_details import get_item_details

for checked_item in checked_values:
item_line = self.append("items", {})
price_list, price_list_currency = frappe.db.get_values(
"Price List", {"selling": 1}, ["name", "currency"]
)[0]
args = {
"doctype": "Sales Invoice",
"item_code": checked_item["item"],
"company": self.company,
"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_line.item_code = checked_item["item"]
item_line.qty = 1
if checked_item["qty"]:
item_line.qty = checked_item["qty"]
if checked_item["rate"]:
item_line.rate = checked_item["rate"]
else:
item_line.rate = item_details.price_list_rate
item_line.amount = float(item_line.rate) * float(item_line.qty)
if checked_item["income_account"]:
item_line.income_account = checked_item["income_account"]
if checked_item["dt"]:
item_line.reference_dt = checked_item["dt"]
if checked_item["dn"]:
item_line.reference_dn = checked_item["dn"]
if checked_item["description"]:
item_line.description = checked_item["description"]

self.set_missing_values(for_validate=True)

+ 29
- 0
healthcare/healthcare/custom_doctype/test_sales_invoice.py Vedi File

@@ -0,0 +1,29 @@
import frappe
from frappe.tests.utils import FrappeTestCase

test_records = frappe.get_test_records("Sales Invoice")


class TestSalesInvoice(FrappeTestCase):
def test_set_healthcare_services_should_preserve_state(self):
invoice = frappe.copy_doc(test_records[0])

count = len(invoice.items)
item = invoice.items[0]
checked_values = [
{
"dt": "Item",
"dn": item.item_name,
"item": item.item_code,
"qty": False,
"rate": False,
"income_account": False,
"description": False,
}
]

invoice.set_healthcare_services(checked_values)
self.assertEqual(count + 1, len(invoice.items))

invoice.set_healthcare_services(checked_values)
self.assertEqual(count + 2, len(invoice.items))

+ 26
- 0
healthcare/healthcare/dashboard_chart/clinical_procedures/clinical_procedures.json Vedi File

@@ -0,0 +1,26 @@
{
"chart_name": "Clinical Procedures",
"chart_type": "Group By",
"creation": "2020-07-14 18:17:54.601236",
"docstatus": 0,
"doctype": "Dashboard Chart",
"document_type": "Clinical Procedure",
"dynamic_filters_json": "[[\"Clinical Procedure\",\"company\",\"=\",\"frappe.defaults.get_user_default(\\\"Company\\\")\"]]",
"filters_json": "[[\"Clinical Procedure\",\"docstatus\",\"=\",\"1\",false]]",
"group_by_based_on": "procedure_template",
"group_by_type": "Count",
"idx": 0,
"is_public": 1,
"is_standard": 1,
"last_synced_on": "2021-01-30 21:03:30.086891",
"modified": "2021-02-01 13:36:04.469863",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Clinical Procedures",
"number_of_groups": 0,
"owner": "Administrator",
"timeseries": 0,
"type": "Bar",
"use_report_chart": 0,
"y_axis": []
}

+ 26
- 0
healthcare/healthcare/dashboard_chart/clinical_procedures_status/clinical_procedures_status.json Vedi File

@@ -0,0 +1,26 @@
{
"chart_name": "Clinical Procedure Status",
"chart_type": "Group By",
"creation": "2020-07-14 18:17:54.654325",
"docstatus": 0,
"doctype": "Dashboard Chart",
"document_type": "Clinical Procedure",
"dynamic_filters_json": "[[\"Clinical Procedure\",\"company\",\"=\",\"frappe.defaults.get_user_default(\\\"Company\\\")\"]]",
"filters_json": "[[\"Clinical Procedure\",\"docstatus\",\"=\",\"1\",false]]",
"group_by_based_on": "status",
"group_by_type": "Count",
"idx": 0,
"is_public": 1,
"is_standard": 1,
"last_synced_on": "2021-02-01 13:36:38.787783",
"modified": "2021-02-01 13:37:18.718275",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Clinical Procedures Status",
"number_of_groups": 0,
"owner": "Administrator",
"timeseries": 0,
"type": "Bar",
"use_report_chart": 0,
"y_axis": []
}

+ 25
- 0
healthcare/healthcare/dashboard_chart/department_wise_patient_appointments/department_wise_patient_appointments.json Vedi File

@@ -0,0 +1,25 @@
{
"chart_name": "Department wise Patient Appointments",
"chart_type": "Custom",
"creation": "2020-07-17 11:25:37.190130",
"custom_options": "{\"colors\": [\"#7CD5FA\", \"#5F62F6\", \"#7544E2\", \"#EE5555\"], \"barOptions\": {\"stacked\": 1}, \"height\": 300}",
"docstatus": 0,
"doctype": "Dashboard Chart",
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\"}",
"filters_json": "{}",
"idx": 0,
"is_public": 1,
"is_standard": 1,
"last_synced_on": "2020-07-22 15:32:05.827566",
"modified": "2020-07-22 15:35:12.798035",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Department wise Patient Appointments",
"number_of_groups": 0,
"owner": "Administrator",
"source": "Department wise Patient Appointments",
"timeseries": 0,
"type": "Bar",
"use_report_chart": 0,
"y_axis": []
}

+ 26
- 0
healthcare/healthcare/dashboard_chart/diagnoses/diagnoses.json Vedi File

@@ -0,0 +1,26 @@
{
"chart_name": "Diagnoses",
"chart_type": "Group By",
"creation": "2020-07-14 18:17:54.705698",
"docstatus": 0,
"doctype": "Dashboard Chart",
"document_type": "Patient Encounter Diagnosis",
"dynamic_filters_json": "",
"filters_json": "[]",
"group_by_based_on": "diagnosis",
"group_by_type": "Count",
"idx": 0,
"is_public": 1,
"is_standard": 1,
"last_synced_on": "2021-01-30 21:03:33.729487",
"modified": "2021-02-01 13:34:57.385335",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Diagnoses",
"number_of_groups": 0,
"owner": "Administrator",
"timeseries": 0,
"type": "Bar",
"use_report_chart": 0,
"y_axis": []
}

+ 26
- 0
healthcare/healthcare/dashboard_chart/in_patient_status/in_patient_status.json Vedi File

@@ -0,0 +1,26 @@
{
"chart_name": "In-Patient Status",
"chart_type": "Group By",
"creation": "2020-07-14 18:17:54.629199",
"docstatus": 0,
"doctype": "Dashboard Chart",
"document_type": "Inpatient Record",
"dynamic_filters_json": "[[\"Inpatient Record\",\"company\",\"=\",\"frappe.defaults.get_user_default(\\\"Company\\\")\"]]",
"filters_json": "[]",
"group_by_based_on": "status",
"group_by_type": "Count",
"idx": 0,
"is_public": 1,
"is_standard": 1,
"last_synced_on": "2020-07-22 13:22:46.792131",
"modified": "2020-07-22 13:33:16.008150",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "In-Patient Status",
"number_of_groups": 0,
"owner": "Administrator",
"timeseries": 0,
"type": "Bar",
"use_report_chart": 0,
"y_axis": []
}

+ 26
- 0
healthcare/healthcare/dashboard_chart/lab_tests/lab_tests.json Vedi File

@@ -0,0 +1,26 @@
{
"chart_name": "Lab Tests",
"chart_type": "Group By",
"creation": "2020-07-14 18:17:54.574903",
"docstatus": 0,
"doctype": "Dashboard Chart",
"document_type": "Lab Test",
"dynamic_filters_json": "[[\"Lab Test\",\"company\",\"=\",\"frappe.defaults.get_user_default(\\\"Company\\\")\"]]",
"filters_json": "[[\"Lab Test\",\"docstatus\",\"=\",\"1\",false]]",
"group_by_based_on": "template",
"group_by_type": "Count",
"idx": 0,
"is_public": 1,
"is_standard": 1,
"last_synced_on": "2021-01-30 21:03:28.272914",
"modified": "2021-02-01 13:36:08.391433",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Lab Tests",
"number_of_groups": 0,
"owner": "Administrator",
"timeseries": 0,
"type": "Bar",
"use_report_chart": 0,
"y_axis": []
}

+ 27
- 0
healthcare/healthcare/dashboard_chart/patient_appointments/patient_appointments.json Vedi File

@@ -0,0 +1,27 @@
{
"based_on": "appointment_datetime",
"chart_name": "Patient Appointments",
"chart_type": "Count",
"creation": "2020-07-14 18:17:54.525082",
"docstatus": 0,
"doctype": "Dashboard Chart",
"document_type": "Patient Appointment",
"dynamic_filters_json": "[[\"Patient Appointment\",\"company\",\"=\",\"frappe.defaults.get_user_default(\\\"Company\\\")\"]]",
"filters_json": "[[\"Patient Appointment\",\"status\",\"!=\",\"Cancelled\",false]]",
"idx": 0,
"is_public": 0,
"is_standard": 1,
"last_synced_on": "2020-07-22 13:22:46.830491",
"modified": "2020-07-22 13:38:02.254190",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Patient Appointments",
"number_of_groups": 0,
"owner": "Administrator",
"time_interval": "Daily",
"timeseries": 1,
"timespan": "Last Month",
"type": "Line",
"use_report_chart": 0,
"y_axis": []
}

+ 26
- 0
healthcare/healthcare/dashboard_chart/symptoms/symptoms.json Vedi File

@@ -0,0 +1,26 @@
{
"chart_name": "Symptoms",
"chart_type": "Group By",
"creation": "2020-07-14 18:17:54.680852",
"docstatus": 0,
"doctype": "Dashboard Chart",
"document_type": "Patient Encounter Symptom",
"dynamic_filters_json": "",
"filters_json": "[]",
"group_by_based_on": "complaint",
"group_by_type": "Count",
"idx": 0,
"is_public": 1,
"is_standard": 1,
"last_synced_on": "2021-01-30 21:03:32.067473",
"modified": "2021-02-01 13:35:30.953718",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Symptoms",
"number_of_groups": 0,
"owner": "Administrator",
"timeseries": 0,
"type": "Bar",
"use_report_chart": 0,
"y_axis": []
}

+ 0
- 0
healthcare/healthcare/dashboard_chart_source/__init__.py Vedi File


+ 0
- 0
healthcare/healthcare/dashboard_chart_source/department_wise_patient_appointments/__init__.py Vedi File


+ 14
- 0
healthcare/healthcare/dashboard_chart_source/department_wise_patient_appointments/department_wise_patient_appointments.js Vedi File

@@ -0,0 +1,14 @@
frappe.provide('frappe.dashboards.chart_sources');

frappe.dashboards.chart_sources["Department wise Patient Appointments"] = {
method: "healthcare.healthcare.dashboard_chart_source.department_wise_patient_appointments.department_wise_patient_appointments.get",
filters: [
{
fieldname: "company",
label: __("Company"),
fieldtype: "Link",
options: "Company",
default: frappe.defaults.get_user_default("Company")
}
]
};

+ 13
- 0
healthcare/healthcare/dashboard_chart_source/department_wise_patient_appointments/department_wise_patient_appointments.json Vedi File

@@ -0,0 +1,13 @@
{
"creation": "2020-05-18 19:18:42.571045",
"docstatus": 0,
"doctype": "Dashboard Chart Source",
"idx": 0,
"modified": "2020-05-18 19:18:42.571045",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Department wise Patient Appointments",
"owner": "Administrator",
"source_name": "Department wise Patient Appointments",
"timeseries": 0
}

+ 70
- 0
healthcare/healthcare/dashboard_chart_source/department_wise_patient_appointments/department_wise_patient_appointments.py Vedi File

@@ -0,0 +1,70 @@
# Copyright (c) 2015, InfluxERP
# License: GNU General Public License v3. See license.txt


import frappe
from frappe.utils.dashboard import cache_source


@frappe.whitelist()
@cache_source
def get(
chart_name=None,
chart=None,
no_cache=None,
filters=None,
from_date=None,
to_date=None,
timespan=None,
time_interval=None,
heatmap_year=None,
):
if chart_name:
chart = frappe.get_doc("Dashboard Chart", chart_name)
else:
chart = frappe._dict(frappe.parse_json(chart))

filters = frappe.parse_json(filters)

data = frappe.db.get_list("Medical Department", fields=["name"])
if not filters:
filters = {}

status = ["Open", "Scheduled", "Closed", "Cancelled"]
for department in data:
filters["department"] = department.name
department["total_appointments"] = frappe.db.count("Patient Appointment", filters=filters)

for entry in status:
filters["status"] = entry
department[frappe.scrub(entry)] = frappe.db.count("Patient Appointment", filters=filters)
filters.pop("status")

sorted_department_map = sorted(data, key=lambda i: i["total_appointments"], reverse=True)

if len(sorted_department_map) > 10:
sorted_department_map = sorted_department_map[:10]

labels = []
open_appointments = []
scheduled = []
closed = []
cancelled = []

for department in sorted_department_map:
labels.append(department.name)
open_appointments.append(department.open)
scheduled.append(department.scheduled)
closed.append(department.closed)
cancelled.append(department.cancelled)

return {
"labels": labels,
"datasets": [
{"name": "Open", "values": open_appointments},
{"name": "Scheduled", "values": scheduled},
{"name": "Closed", "values": closed},
{"name": "Cancelled", "values": cancelled},
],
"type": "bar",
}

+ 122
- 0
healthcare/healthcare/desk_page/healthcare/healthcare.json Vedi File

@@ -0,0 +1,122 @@
{
"cards": [
{
"hidden": 0,
"label": "Masters",
"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]"
},
{
"hidden": 0,
"label": "Consultation Setup",
"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]"
},
{
"hidden": 0,
"label": "Consultation",
"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]"
},
{
"hidden": 0,
"label": "Settings",
"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]"
},
{
"hidden": 0,
"label": "Laboratory Setup",
"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]"
},
{
"hidden": 0,
"label": "Laboratory",
"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]"
},
{
"hidden": 0,
"label": "Inpatient",
"links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Inpatient Record\",\n\t\t\"label\": \"Inpatient Record\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Inpatient Medication Order\",\n\t\t\"label\": \"Inpatient Medication Order\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Inpatient Medication Entry\",\n\t\t\"label\": \"Inpatient Medication Entry\"\n\t}\n]"
},
{
"hidden": 0,
"label": "Rehabilitation and Physiotherapy",
"links": "[\n {\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Exercise Type\",\n\t\t\"label\": \"Exercise Type\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Therapy Type\",\n\t\t\"label\": \"Therapy Type\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Therapy Plan\",\n\t\t\"label\": \"Therapy Plan\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Therapy Session\",\n\t\t\"label\": \"Therapy Session\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Assessment Template\",\n\t\t\"label\": \"Patient Assessment Template\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Assessment\",\n\t\t\"label\": \"Patient Assessment\"\n\t}\n]"
},
{
"hidden": 0,
"label": "Records and History",
"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\": \"page\",\n\t\t\"name\": \"patient-progress\",\n\t\t\"label\": \"Patient Progress\"\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]"
},
{
"hidden": 0,
"label": "Reports",
"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\t{\n\t\t\"type\": \"report\",\n\t\t\"is_query_report\": true,\n\t\t\"name\": \"Inpatient Medication Orders\",\n\t\t\"doctype\": \"Inpatient Medication Order\",\n\t\t\"label\": \"Inpatient Medication Orders\"\n\t}\n]"
}
],
"category": "Domains",
"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,
"docstatus": 0,
"doctype": "Desk Page",
"extends_another_page": 0,
"hide_custom": 0,
"idx": 0,
"is_standard": 1,
"label": "Healthcare",
"modified": "2020-11-26 22:09:09.164584",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Healthcare",
"onboarding": "Healthcare",
"owner": "Administrator",
"pin_to_bottom": 0,
"pin_to_top": 0,
"restrict_to_domain": "Healthcare",
"shortcuts": [
{
"color": "#ffe8cd",
"format": "{} Open",
"label": "Patient Appointment",
"link_to": "Patient Appointment",
"stats_filter": "{\n \"status\": \"Open\",\n \"company\": [\"like\", '%' + frappe.defaults.get_global_default(\"company\") + '%']\n}",
"type": "DocType"
},
{
"color": "#ffe8cd",
"format": "{} Active",
"label": "Patient",
"link_to": "Patient",
"stats_filter": "{\n \"status\": \"Active\"\n}",
"type": "DocType"
},
{
"color": "#cef6d1",
"format": "{} Vacant",
"label": "Healthcare Service Unit",
"link_to": "Healthcare Service Unit",
"stats_filter": "{\n \"occupancy_status\": \"Vacant\",\n \"is_group\": 0,\n \"company\": [\"like\", \"%\" + frappe.defaults.get_global_default(\"company\") + \"%\"]\n}",
"type": "DocType"
},
{
"label": "Healthcare Practitioner",
"link_to": "Healthcare Practitioner",
"type": "DocType"
},
{
"label": "Patient History",
"link_to": "patient_history",
"type": "Page"
},
{
"label": "Dashboard",
"link_to": "Healthcare",
"type": "Dashboard"
}
]
}

+ 0
- 0
healthcare/healthcare/doctype/__init__.py Vedi File


+ 0
- 0
healthcare/healthcare/doctype/antibiotic/__init__.py Vedi File


+ 5
- 0
healthcare/healthcare/doctype/antibiotic/antibiotic.js Vedi File

@@ -0,0 +1,5 @@
// Copyright (c) 2017, InfluxERP
// For license information, please see license.txt

frappe.ui.form.on('Antibiotic', {
});

+ 151
- 0
healthcare/healthcare/doctype/antibiotic/antibiotic.json Vedi File

@@ -0,0 +1,151 @@
{
"allow_copy": 1,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:antibiotic_name",
"beta": 1,
"creation": "2016-02-23 11:11:30.749731",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
"editable_grid": 0,
"fields": [
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "antibiotic_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": "Antibiotic 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": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "abbr",
"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": "Abbr",
"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": 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-10-01 17:58:23.136498",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Antibiotic",
"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": 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
}
],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"restrict_to_domain": "Healthcare",
"search_fields": "antibiotic_name",
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "antibiotic_name",
"track_changes": 0,
"track_seen": 0,
"track_views": 0
}

+ 10
- 0
healthcare/healthcare/doctype/antibiotic/antibiotic.py Vedi File

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, InfluxERP
# For license information, please see license.txt


from frappe.model.document import Document


class Antibiotic(Document):
pass

+ 10
- 0
healthcare/healthcare/doctype/antibiotic/test_antibiotic.py Vedi File

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, InfluxERP
# See license.txt


from frappe.tests.utils import FrappeTestCase


class TestAntibiotic(FrappeTestCase):
pass

+ 0
- 0
healthcare/healthcare/doctype/appointment_type/__init__.py Vedi File


+ 83
- 0
healthcare/healthcare/doctype/appointment_type/appointment_type.js Vedi File

@@ -0,0 +1,83 @@
// Copyright (c) 2016, ESS LLP and contributors
// For license information, please see license.txt

frappe.ui.form.on('Appointment Type', {
refresh: function(frm) {
frm.set_query('price_list', function() {
return {
filters: {'selling': 1}
};
});

frm.set_query('medical_department', 'items', function(doc) {
let item_list = doc.items.map(({medical_department}) => medical_department);
return {
filters: [
['Medical Department', 'name', 'not in', item_list]
]
};
});

frm.set_query('op_consulting_charge_item', 'items', function() {
return {
filters: {
is_stock_item: 0
}
};
});

frm.set_query('inpatient_visit_charge_item', 'items', function() {
return {
filters: {
is_stock_item: 0
}
};
});
}
});

frappe.ui.form.on('Appointment Type Service Item', {
op_consulting_charge_item: function(frm, cdt, cdn) {
let d = locals[cdt][cdn];
if (frm.doc.price_list && d.op_consulting_charge_item) {
frappe.call({
'method': 'frappe.client.get_value',
args: {
'doctype': 'Item Price',
'filters': {
'item_code': d.op_consulting_charge_item,
'price_list': frm.doc.price_list
},
'fieldname': ['price_list_rate']
},
callback: function(data) {
if (data.message.price_list_rate) {
frappe.model.set_value(cdt, cdn, 'op_consulting_charge', data.message.price_list_rate);
}
}
});
}
},

inpatient_visit_charge_item: function(frm, cdt, cdn) {
let d = locals[cdt][cdn];
if (frm.doc.price_list && d.inpatient_visit_charge_item) {
frappe.call({
'method': 'frappe.client.get_value',
args: {
'doctype': 'Item Price',
'filters': {
'item_code': d.inpatient_visit_charge_item,
'price_list': frm.doc.price_list
},
'fieldname': ['price_list_rate']
},
callback: function (data) {
if (data.message.price_list_rate) {
frappe.model.set_value(cdt, cdn, 'inpatient_visit_charge', data.message.price_list_rate);
}
}
});
}
}
});

+ 114
- 0
healthcare/healthcare/doctype/appointment_type/appointment_type.json Vedi File

@@ -0,0 +1,114 @@
{
"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",
"billing_section",
"price_list",
"items"
],
"fields": [
{
"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
},
{
"bold": 1,
"default": "0",
"fieldname": "ip",
"fieldtype": "Check",
"label": "Is Inpatient",
"print_hide": 1,
"report_hide": 1
},
{
"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_in_quick_entry": 1,
"fieldname": "color",
"fieldtype": "Color",
"in_list_view": 1,
"label": "Color",
"no_copy": 1,
"report_hide": 1
},
{
"fieldname": "billing_section",
"fieldtype": "Section Break",
"label": "Billing"
},
{
"fieldname": "price_list",
"fieldtype": "Link",
"label": "Price List",
"options": "Price List"
},
{
"fieldname": "items",
"fieldtype": "Table",
"label": "Appointment Type Service Items",
"options": "Appointment Type Service Item"
}
],
"links": [],
"modified": "2021-01-22 09:41:05.010524",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Appointment Type",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Healthcare Administrator",
"share": 1,
"write": 1
},
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Physician",
"share": 1,
"write": 1
}
],
"quick_entry": 1,
"restrict_to_domain": "Healthcare",
"search_fields": "appointment_type",
"sort_field": "modified",
"sort_order": "DESC"
}

+ 75
- 0
healthcare/healthcare/doctype/appointment_type/appointment_type.py Vedi File

@@ -0,0 +1,75 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, ESS LLP and contributors
# For license information, please see license.txt


import frappe
from frappe.model.document import Document


class AppointmentType(Document):
def validate(self):
if self.items and self.price_list:
for item in self.items:
existing_op_item_price = frappe.db.exists(
"Item Price", {"item_code": item.op_consulting_charge_item, "price_list": self.price_list}
)

if not existing_op_item_price and item.op_consulting_charge_item and item.op_consulting_charge:
make_item_price(self.price_list, item.op_consulting_charge_item, item.op_consulting_charge)

existing_ip_item_price = frappe.db.exists(
"Item Price", {"item_code": item.inpatient_visit_charge_item, "price_list": self.price_list}
)

if (
not existing_ip_item_price
and item.inpatient_visit_charge_item
and item.inpatient_visit_charge
):
make_item_price(
self.price_list, item.inpatient_visit_charge_item, item.inpatient_visit_charge
)


@frappe.whitelist()
def get_service_item_based_on_department(appointment_type, department):
item_list = frappe.db.get_value(
"Appointment Type Service Item",
filters={"medical_department": department, "parent": appointment_type},
fieldname=[
"op_consulting_charge_item",
"inpatient_visit_charge_item",
"op_consulting_charge",
"inpatient_visit_charge",
],
as_dict=1,
)

# if department wise items are not set up
# use the generic items
if not item_list:
item_list = frappe.db.get_value(
"Appointment Type Service Item",
filters={"parent": appointment_type},
fieldname=[
"op_consulting_charge_item",
"inpatient_visit_charge_item",
"op_consulting_charge",
"inpatient_visit_charge",
],
as_dict=1,
)

return item_list


def make_item_price(price_list, item, item_price):
frappe.get_doc(
{
"doctype": "Item Price",
"price_list": price_list,
"item_code": item,
"price_list_rate": item_price,
}
).insert(ignore_permissions=True, ignore_mandatory=True)

+ 10
- 0
healthcare/healthcare/doctype/appointment_type/appointment_type_dashboard.py Vedi File

@@ -0,0 +1,10 @@
from frappe import _


def get_data():
return {
"fieldname": "appointment_type",
"transactions": [
{"label": _("Patient Appointments"), "items": ["Patient Appointment"]},
],
}

+ 12
- 0
healthcare/healthcare/doctype/appointment_type/test_appointment_type.py Vedi File

@@ -0,0 +1,12 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, ESS LLP and Contributors
# See license.txt


from frappe.tests.utils import FrappeTestCase

# test_records = frappe.get_test_records('Appointment Type')


class TestAppointmentType(FrappeTestCase):
pass

+ 0
- 0
healthcare/healthcare/doctype/appointment_type_service_item/__init__.py Vedi File


+ 67
- 0
healthcare/healthcare/doctype/appointment_type_service_item/appointment_type_service_item.json Vedi File

@@ -0,0 +1,67 @@
{
"actions": [],
"creation": "2021-01-22 09:34:53.373105",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"medical_department",
"op_consulting_charge_item",
"op_consulting_charge",
"column_break_4",
"inpatient_visit_charge_item",
"inpatient_visit_charge"
],
"fields": [
{
"fieldname": "medical_department",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Medical Department",
"options": "Medical Department"
},
{
"fieldname": "op_consulting_charge_item",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Out Patient Consulting Charge Item",
"options": "Item"
},
{
"fieldname": "op_consulting_charge",
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Out Patient Consulting Charge"
},
{
"fieldname": "column_break_4",
"fieldtype": "Column Break"
},
{
"fieldname": "inpatient_visit_charge_item",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Inpatient Visit Charge Item",
"options": "Item"
},
{
"fieldname": "inpatient_visit_charge",
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Inpatient Visit Charge"
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2021-08-17 06:05:02.240812",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Appointment Type Service Item",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

+ 11
- 0
healthcare/healthcare/doctype/appointment_type_service_item/appointment_type_service_item.py Vedi File

@@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2021, InfluxERP
# For license information, please see license.txt


# import frappe
from frappe.model.document import Document


class AppointmentTypeServiceItem(Document):
pass

+ 0
- 0
healthcare/healthcare/doctype/body_part/__init__.py Vedi File


+ 8
- 0
healthcare/healthcare/doctype/body_part/body_part.js Vedi File

@@ -0,0 +1,8 @@
// Copyright (c) 2020, InfluxERP
// For license information, please see license.txt

frappe.ui.form.on('Body Part', {
// refresh: function(frm) {

// }
});

+ 45
- 0
healthcare/healthcare/doctype/body_part/body_part.json Vedi File

@@ -0,0 +1,45 @@
{
"actions": [],
"autoname": "field:body_part",
"creation": "2020-04-10 12:21:55.036402",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"body_part"
],
"fields": [
{
"fieldname": "body_part",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Body Part",
"reqd": 1,
"unique": 1
}
],
"links": [],
"modified": "2020-04-10 12:26:44.087985",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Body Part",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

+ 11
- 0
healthcare/healthcare/doctype/body_part/body_part.py Vedi File

@@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020, InfluxERP
# For license information, please see license.txt


# import frappe
from frappe.model.document import Document


class BodyPart(Document):
pass

+ 11
- 0
healthcare/healthcare/doctype/body_part/test_body_part.py Vedi File

@@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020, InfluxERP
# See license.txt


# import frappe
from frappe.tests.utils import FrappeTestCase


class TestBodyPart(FrappeTestCase):
pass

+ 0
- 0
healthcare/healthcare/doctype/body_part_link/__init__.py Vedi File


+ 32
- 0
healthcare/healthcare/doctype/body_part_link/body_part_link.json Vedi File

@@ -0,0 +1,32 @@
{
"actions": [],
"creation": "2020-04-10 12:23:15.259816",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"body_part"
],
"fields": [
{
"fieldname": "body_part",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Body Part",
"options": "Body Part",
"reqd": 1
}
],
"istable": 1,
"links": [],
"modified": "2020-04-10 12:25:23.101749",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Body Part Link",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

+ 11
- 0
healthcare/healthcare/doctype/body_part_link/body_part_link.py Vedi File

@@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020, InfluxERP
# For license information, please see license.txt


# import frappe
from frappe.model.document import Document


class BodyPartLink(Document):
pass

+ 0
- 0
healthcare/healthcare/doctype/clinical_procedure/__init__.py Vedi File


+ 377
- 0
healthcare/healthcare/doctype/clinical_procedure/clinical_procedure.js Vedi File

@@ -0,0 +1,377 @@
// Copyright (c) 2017, ESS LLP and contributors
// For license information, please see license.txt

frappe.ui.form.on('Clinical Procedure', {
setup: function(frm) {
frm.set_query('batch_no', 'items', function(doc, cdt, cdn) {
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') {
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',
filters: filters
};
}
});
},

refresh: function(frm) {
frm.set_query('patient', function () {
return {
filters: {'status': ['!=', 'Disabled']}
};
});

frm.set_query('appointment', function () {
return {
filters: {
'procedure_template': ['not in', null],
'status': ['in', 'Open, Scheduled']
}
};
});

frm.set_query('service_unit', function() {
return {
filters: {
'is_group': false,
'allow_appointments': true,
'company': frm.doc.company
}
};
});

frm.set_query('practitioner', function() {
return {
filters: {
'department': frm.doc.medical_department
}
};
});

if (frm.doc.consume_stock) {
frm.set_indicator_formatter('item_code',
function(doc) { return (doc.qty<=doc.actual_qty) ? 'green' : 'orange' ; });
}

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]);
}

frm.add_custom_button(__(btn_label), function () {
frappe.confirm(
msg,
function() {
frappe.call({
method: 'complete_procedure',
doc: frm.doc,
freeze: true,
callback: function(r) {
if (r.message) {
frappe.show_alert({
message: __('Stock Entry {0} created', ['<a class="bold" href="/app/stock-entry/'+ r.message + '">' + r.message + '</a>']),
indicator: 'green'
});
}
frm.reload_doc();
}
});
}
);
}).addClass("btn-primary");

} 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',
freeze: true,
callback: function(r) {
if (!r.exc) {
frm.reload_doc();
let doclist = frappe.model.sync(r.message);
frappe.set_route('Form', doclist[0].doctype, doclist[0].name);
}
}
});
}
);
} else {
frm.reload_doc();
}
}
}
});
}).addClass("btn-primary");
}
}
},

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) {
frappe.call({
'method': 'healthcare.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);
} else if (data.message.age) {
age = data.message.age;
if (data.message.age_as_on) {
age = __('{0} as on {1}', [age, data.message.age_as_on]);
}
}
frm.set_value('patient_name', data.message.patient_name);
frm.set_value('patient_age', age);
frm.set_value('patient_sex', data.message.sex);
}
});
} else {
frm.set_value('patient_name', '');
frm.set_value('patient_age', '');
frm.set_value('patient_sex', '');
}
},

appointment: function(frm) {
if (frm.doc.appointment) {
frappe.call({
'method': 'frappe.client.get',
args: {
doctype: 'Patient Appointment',
name: frm.doc.appointment
},
callback: function(data) {
let values = {
'patient':data.message.patient,
'procedure_template': data.message.procedure_template,
'medical_department': data.message.department,
'practitioner': data.message.practitioner,
'start_date': data.message.appointment_date,
'start_time': data.message.appointment_time,
'notes': data.message.notes,
'service_unit': data.message.service_unit,
'company': data.message.company
};
frm.set_value(values);
}
});
} else {
let values = {
'patient': '',
'patient_name': '',
'patient_sex': '',
'patient_age': '',
'medical_department': '',
'procedure_template': '',
'start_date': '',
'start_time': '',
'notes': '',
'service_unit': '',
'inpatient_record': ''
};
frm.set_value(values);
}
},

procedure_template: function(frm) {
if (frm.doc.procedure_template) {
frappe.call({
'method': 'frappe.client.get',
args: {
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);
frm.events.set_warehouse(frm);
frm.events.set_procedure_consumables(frm);
}
});
}
},

service_unit: function(frm) {
if (frm.doc.service_unit) {
frappe.call({
method: 'frappe.client.get_value',
args:{
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);
}
}
});
}
},

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, 'practitioner_name', data.message.practitioner_name);
}
});
} else {
frappe.model.set_value(frm.doctype,frm.docname, 'practitioner_name', '');
}
},

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: 'healthcare.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');
}
}
});
}

});

frappe.ui.form.on('Clinical Procedure Item', {
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) {
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',
args: {
item_code: d.item_code,
uom: d.uom,
qty: d.qty
},
callback: function(r) {
if (r.message) {
frappe.model.set_value(cdt, cdn, r.message);
}
}
});
}
},

item_code: function(frm, cdt, cdn) {
let d = locals[cdt][cdn];
let args = null;
if (d.item_code) {
args = {
'doctype' : 'Clinical Procedure',
'item_code' : d.item_code,
'company' : frm.doc.company,
'warehouse': frm.doc.warehouse
};
return frappe.call({
method: 'healthcare.healthcare.doctype.clinical_procedure_template.clinical_procedure_template.get_item_details',
args: {args: args},
callback: function(r) {
if (r.message) {
let d = locals[cdt][cdn];
$.each(r.message, function(k, v) {
d[k] = v;
});
refresh_field('items');
}
}
});
}
}
});

let calculate_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} ${__('Years(s)')} ${age.getMonth()} ${__('Month(s)')} ${age.getDate()} ${__('Day(s)')}`;
};

// List Stock items
cur_frm.set_query('item_code', 'items', function() {
return {
filters: {
is_stock_item:1
}
};
});

+ 351
- 0
healthcare/healthcare/doctype/clinical_procedure/clinical_procedure.json Vedi File

@@ -0,0 +1,351 @@
{
"actions": [],
"autoname": "naming_series:",
"beta": 1,
"creation": "2017-04-07 12:52:43.542429",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"naming_series",
"title",
"appointment",
"procedure_template",
"medical_code",
"column_break_30",
"company",
"invoiced",
"section_break_6",
"patient",
"patient_name",
"patient_sex",
"patient_age",
"inpatient_record",
"notes",
"column_break_7",
"status",
"practitioner",
"practitioner_name",
"medical_department",
"service_unit",
"start_date",
"start_time",
"sample",
"consumables_section",
"consume_stock",
"warehouse",
"items",
"section_break_24",
"invoice_separately_as_consumables",
"consumption_invoiced",
"consumable_total_amount",
"column_break_27",
"consumption_details",
"sb_refs",
"column_break_34",
"prescription",
"amended_from"
],
"fields": [
{
"fetch_from": "patient.inpatient_record",
"fieldname": "inpatient_record",
"fieldtype": "Link",
"label": "Inpatient Record",
"options": "Inpatient Record",
"read_only": 1
},
{
"fieldname": "naming_series",
"fieldtype": "Select",
"label": "Series",
"options": "HLC-CPR-.YYYY.-"
},
{
"fieldname": "appointment",
"fieldtype": "Link",
"in_standard_filter": 1,
"label": "Appointment",
"options": "Patient Appointment",
"set_only_once": 1
},
{
"fieldname": "patient",
"fieldtype": "Link",
"in_standard_filter": 1,
"label": "Patient",
"options": "Patient",
"reqd": 1
},
{
"fieldname": "patient_age",
"fieldtype": "Data",
"label": "Age",
"read_only": 1
},
{
"fieldname": "patient_sex",
"fieldtype": "Link",
"label": "Gender",
"options": "Gender",
"read_only": 1,
"set_only_once": 1
},
{
"fieldname": "prescription",
"fieldtype": "Link",
"hidden": 1,
"label": "Procedure Prescription",
"options": "Procedure Prescription",
"read_only": 1
},
{
"fieldname": "medical_department",
"fieldtype": "Link",
"in_standard_filter": 1,
"label": "Medical Department",
"options": "Medical Department"
},
{
"fieldname": "practitioner",
"fieldtype": "Link",
"in_standard_filter": 1,
"label": "Healthcare Practitioner",
"options": "Healthcare Practitioner"
},
{
"fieldname": "column_break_7",
"fieldtype": "Column Break"
},
{
"fieldname": "procedure_template",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Procedure Template",
"options": "Clinical Procedure Template",
"reqd": 1
},
{
"fieldname": "service_unit",
"fieldtype": "Link",
"label": "Service Unit",
"options": "Healthcare Service Unit",
"set_only_once": 1
},
{
"fieldname": "warehouse",
"fieldtype": "Link",
"label": "Warehouse",
"mandatory_depends_on": "eval: doc.consume_stock == 1",
"options": "Warehouse"
},
{
"default": "Today",
"fieldname": "start_date",
"fieldtype": "Date",
"label": "Start Date"
},
{
"fieldname": "start_time",
"fieldtype": "Time",
"label": "Start Time"
},
{
"fieldname": "sample",
"fieldtype": "Link",
"label": "Sample",
"options": "Sample Collection"
},
{
"default": "0",
"fieldname": "invoiced",
"fieldtype": "Check",
"label": "Invoiced",
"no_copy": 1,
"read_only": 1
},
{
"fieldname": "notes",
"fieldtype": "Small Text",
"label": "Notes",
"set_only_once": 1
},
{
"fieldname": "company",
"fieldtype": "Link",
"label": "Company",
"options": "Company"
},
{
"default": "0",
"fieldname": "consume_stock",
"fieldtype": "Check",
"label": "Consume Stock"
},
{
"fieldname": "items",
"fieldtype": "Table",
"label": "Consumables",
"options": "Clinical Procedure Item"
},
{
"default": "0",
"fieldname": "invoice_separately_as_consumables",
"fieldtype": "Check",
"hidden": 1,
"label": "Invoice Consumables Separately",
"read_only": 1
},
{
"depends_on": "invoice_separately_as_consumables",
"fieldname": "consumable_total_amount",
"fieldtype": "Currency",
"label": "Consumable Total Amount",
"read_only": 1
},
{
"depends_on": "invoice_separately_as_consumables",
"fieldname": "consumption_details",
"fieldtype": "Small Text",
"label": "Consumption Details"
},
{
"default": "0",
"depends_on": "invoice_separately_as_consumables",
"fieldname": "consumption_invoiced",
"fieldtype": "Check",
"hidden": 1,
"label": "Consumption Invoiced",
"read_only": 1
},
{
"depends_on": "eval:!doc.__islocal",
"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
},
{
"fieldname": "amended_from",
"fieldtype": "Link",
"label": "Amended From",
"no_copy": 1,
"options": "Clinical Procedure",
"print_hide": 1,
"read_only": 1
},
{
"collapsible": 1,
"collapsible_depends_on": "consume_stock",
"fieldname": "consumables_section",
"fieldtype": "Section Break",
"label": "Consumables"
},
{
"fieldname": "column_break_27",
"fieldtype": "Column Break"
},
{
"fieldname": "section_break_24",
"fieldtype": "Section Break"
},
{
"fieldname": "column_break_30",
"fieldtype": "Column Break"
},
{
"fieldname": "section_break_6",
"fieldtype": "Section Break"
},
{
"collapsible": 1,
"fieldname": "sb_refs",
"fieldtype": "Section Break"
},
{
"fieldname": "patient_name",
"fieldtype": "Data",
"label": "Patient Name",
"read_only": 1
},
{
"fieldname": "practitioner_name",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Practitioner Name",
"read_only": 1
},
{
"fieldname": "column_break_34",
"fieldtype": "Column Break"
},
{
"allow_on_submit": 1,
"fieldname": "title",
"fieldtype": "Data",
"hidden": 1,
"label": "Title",
"no_copy": 1,
"print_hide": 1,
"read_only": 1
},
{
"fetch_from": "procedure_template.medical_code",
"fieldname": "medical_code",
"fieldtype": "Link",
"label": "Medical Code",
"options": "Medical Code",
"read_only": 1
}
],
"is_submittable": 1,
"links": [
{
"link_doctype": "Nursing Task",
"link_fieldname": "reference_name"
}
],
"modified": "2022-01-17 15:13:55.565922",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Clinical Procedure",
"naming_rule": "By \"Naming Series\" field",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Nursing User",
"share": 1,
"submit": 1,
"write": 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
}
],
"restrict_to_domain": "Healthcare",
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "title",
"track_changes": 1
}

+ 313
- 0
healthcare/healthcare/doctype/clinical_procedure/clinical_procedure.py Vedi File

@@ -0,0 +1,313 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, ESS LLP and contributors
# For license information, please see license.txt

import frappe
from frappe import _
from frappe.model.document import Document
from frappe.model.mapper import get_mapped_doc
from frappe.utils import flt, nowdate, nowtime, now_datetime

from healthcare.healthcare.doctype.healthcare_settings.healthcare_settings import get_account
from healthcare.healthcare.doctype.lab_test.lab_test import create_sample_doc
from erpnext.stock.get_item_details import get_item_details
from erpnext.stock.stock_ledger import get_previous_sle
from healthcare.healthcare.doctype.nursing_task.nursing_task import NursingTask
from healthcare.healthcare.utils import validate_nursing_tasks


class ClinicalProcedure(Document):
def validate(self):
self.set_status()
self.set_title()
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:
self.invoice_separately_as_consumables = True

def before_insert(self):
if self.consume_stock:
self.set_actual_qty()

def after_insert(self):
if self.prescription:
frappe.db.set_value("Procedure Prescription", self.prescription, "procedure_created", 1)
if self.appointment:
frappe.db.set_value("Patient Appointment", self.appointment, "status", "Closed")

if self.procedure_template:
template = frappe.get_doc("Clinical Procedure Template", self.procedure_template)
if template.sample:
patient = frappe.get_doc("Patient", self.patient)
sample_collection = create_sample_doc(template, patient, None, self.company)
frappe.db.set_value("Clinical Procedure", self.name, "sample", sample_collection.name)

self.reload()

def on_submit(self):
self.create_nursing_tasks(post_event=False)

def create_nursing_tasks(self, post_event=True):
if post_event:
template = frappe.db.get_value(
"Clinical Procedure Template", self.procedure_template, "post_op_nursing_checklist_template"
)
start_time = now_datetime()

else:
template = frappe.db.get_value(
"Clinical Procedure Template", self.procedure_template, "pre_op_nursing_checklist_template"
)
# pre op tasks to be created on Clinical Procedure submit, use scheduled date
start_time = frappe.utils.get_datetime(f"{self.start_date} {self.start_time}")

if template:
NursingTask.create_nursing_tasks_from_template(
template, self, start_time=start_time, post_event=post_event
)

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 set_title(self):
self.title = _("{0} - {1}").format(self.patient_name or self.patient, self.procedure_template)[
:100
]

@frappe.whitelist()
def complete_procedure(self):
if self.consume_stock and self.items:
stock_entry = make_stock_entry(self)

if self.items:
consumable_total_amount = 0
consumption_details = False
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"),
)

self.db_set("status", "Completed")

# post op nursing tasks
if self.procedure_template:
self.create_nursing_tasks()

if self.consume_stock and self.items:
return stock_entry

@frappe.whitelist()
def start_procedure(self):
allow_start = self.set_actual_qty()

if allow_start:
validate_nursing_tasks(self)

self.db_set("status", "In Progress")
return "success"

return "insufficient stock"

def set_actual_qty(self):
allow_negative_stock = frappe.db.get_single_value("Stock Settings", "allow_negative_stock")

allow_start = True
for d in self.get("items"):
d.actual_qty = get_stock_qty(d.item_code, self.warehouse)
# validate qty
if not allow_negative_stock and d.actual_qty < d.qty:
allow_start = False
break

return allow_start

@frappe.whitelist()
def make_material_receipt(self, submit=False):
stock_entry = frappe.new_doc("Stock Entry")

stock_entry.stock_entry_type = "Material Receipt"
stock_entry.to_warehouse = self.warehouse
stock_entry.company = 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")
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 - item.actual_qty)
se_child.t_warehouse = self.warehouse
# in stock uom
se_child.transfer_qty = flt(item.transfer_qty)
se_child.conversion_factor = flt(item.conversion_factor)
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()


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
)


@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):
items = get_items("Clinical Procedure Item", stock_detail_parent, parenttype)

for item in items:
se_child = doc.append("items")
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(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_items(table, parent, parenttype):
items = frappe.db.get_all(
table, filters={"parent": parent, "parenttype": parenttype}, fields=["*"]
)

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)

for item_line in stock_entry.items:
cost_center = frappe.get_cached_value("Company", doc.company, "cost_center")
item_line.cost_center = cost_center
item_line.expense_account = expense_account

stock_entry.save(ignore_permissions=True)
stock_entry.submit()
return stock_entry.name


@frappe.whitelist()
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

+ 11
- 0
healthcare/healthcare/doctype/clinical_procedure/clinical_procedure_list.js Vedi File

@@ -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];
}
};

+ 76
- 0
healthcare/healthcare/doctype/clinical_procedure/test_clinical_procedure.py Vedi File

@@ -0,0 +1,76 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, ESS LLP and Contributors
# See license.txt


from frappe.tests.utils import FrappeTestCase

import frappe

from healthcare.healthcare.doctype.patient_appointment.test_patient_appointment import (
create_clinical_procedure_template,
create_healthcare_docs,
)

test_dependencies = ["Item"]


class TestClinicalProcedure(FrappeTestCase):
def test_procedure_template_item(self):
patient, 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.assertEqual(frappe.db.get_value("Item", procedure_template.item, "disabled"), 1)

def test_consumables(self):
patient, 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.company = "_Test Company"
procedure.warehouse = "_Test Warehouse - _TC"
procedure.submit()
return procedure

+ 0
- 0
healthcare/healthcare/doctype/clinical_procedure_item/__init__.py Vedi File


+ 123
- 0
healthcare/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json Vedi File

@@ -0,0 +1,123 @@
{
"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": [
{
"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
},
{
"fieldname": "barcode",
"fieldtype": "Data",
"label": "Barcode"
},
{
"fieldname": "item_name",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Item Name",
"read_only": 1
},
{
"fieldname": "qty",
"fieldtype": "Float",
"in_list_view": 1,
"label": "Quantity",
"reqd": 1
},
{
"fieldname": "uom",
"fieldtype": "Link",
"in_list_view": 1,
"label": "UOM",
"options": "UOM",
"reqd": 1
},
{
"default": "0",
"fieldname": "invoice_separately_as_consumables",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Invoice Separately as Consumables"
},
{
"fieldname": "column_break_5",
"fieldtype": "Column Break"
},
{
"fieldname": "batch_no",
"fieldtype": "Link",
"label": "Batch",
"options": "Batch"
},
{
"fieldname": "conversion_factor",
"fieldtype": "Float",
"label": "Conversion Factor",
"read_only": 1
},
{
"fieldname": "stock_uom",
"fieldtype": "Link",
"label": "Stock UOM",
"options": "UOM",
"read_only": 1,
"reqd": 1
},
{
"fieldname": "transfer_qty",
"fieldtype": "Float",
"label": "Transfer Qty",
"read_only": 1
},
{
"fieldname": "actual_qty",
"fieldtype": "Float",
"label": "Actual Qty (at source/target)",
"no_copy": 1,
"print_hide": 1,
"read_only": 1,
"search_index": 1
}
],
"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
}

+ 10
- 0
healthcare/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.py Vedi File

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, earthians and contributors
# For license information, please see license.txt


from frappe.model.document import Document


class ClinicalProcedureItem(Document):
pass

+ 0
- 0
healthcare/healthcare/doctype/clinical_procedure_template/__init__.py Vedi File


+ 220
- 0
healthcare/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.js Vedi File

@@ -0,0 +1,220 @@
// Copyright (c) 2017, earthians and contributors
// For license information, please see license.txt

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);
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);
},

medical_code: function (frm) {
frm.set_query("medical_code", function () {
return {
filters: {
medical_code_standard: frm.doc.medical_code_standard
}
};
});
},

refresh: function (frm) {
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);
});
}

frm.set_query('item', function() {
return {
filters: {
'disabled': false,
'is_stock_item': false
}
};
});
},

link_existing_item: function (frm) {
if (frm.doc.link_existing_item) {
frm.set_value('item_code', '');
} else {
frm.set_value('item', '');
}
},

item: function (frm) {
if (frm.doc.item) {
frappe.db.get_value('Item', frm.doc.item, ['item_group', 'description'])
.then(r => {
frm.set_value({
'item_group': r.message.item_group,
'description': r.message.description,
'item_code': frm.doc.item
});
})
}
}
});

let mark_change_in_item = function (frm) {
if (!frm.doc.__islocal || frm.doc.link_existing_item) {
frm.doc.change_in_item = 1;
}
};

let change_template_code = function (doc) {
let d = new frappe.ui.Dialog({
title: __('Change Item Code'),
fields: [
{
'fieldtype': 'Data',
'label': 'Item Code',
'fieldname': 'item_code',
reqd: 1
}
],
primary_action: function () {
let values = d.get_values();

if (values) {
frappe.call({
'method': 'healthcare.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
});
};

frappe.ui.form.on('Clinical Procedure Item', {
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) {
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',
args: {
item_code: d.item_code,
uom: d.uom,
qty: d.qty
},
callback: function (r) {
if (r.message) {
frappe.model.set_value(cdt, cdn, r.message);
}
}
});
}
},

item_code: function (frm, cdt, cdn) {
let d = locals[cdt][cdn];
if (d.item_code) {
let args = {
'item_code': d.item_code,
'transfer_qty': d.transfer_qty,
'quantity': d.qty
};
return frappe.call({
method: 'healthcare.healthcare.doctype.clinical_procedure_template.clinical_procedure_template.get_item_details',
args: { args: args },
callback: function (r) {
if (r.message) {
let d = locals[cdt][cdn];
$.each(r.message, function (k, v) {
d[k] = v;
});
refresh_field('items');
}
}
});
}
}
});

// List Stock items
cur_frm.set_query('item_code', 'items', function () {
return {
filters: {
is_stock_item: 1
}
};
});

frappe.tour['Clinical Procedure Template'] = [
{
fieldname: 'template',
title: __('Template Name'),
description: __('Enter a name for the Clinical Procedure Template')
},
{
fieldname: 'item_code',
title: __('Item Code'),
description: __('Set the Item Code which will be used for billing the Clinical Procedure.')
},
{
fieldname: 'item_group',
title: __('Item Group'),
description: __('Select an Item Group for the Clinical Procedure Item.')
},
{
fieldname: 'is_billable',
title: __('Clinical Procedure Rate'),
description: __('Check this if the Clinical Procedure is billable and also set the rate.')
},
{
fieldname: 'consume_stock',
title: __('Allow Stock Consumption'),
description: __('Check this if the Clinical Procedure utilises consumables. Click ') + "<a href='https://frappehealth.com/docs/v13/user/manual/en/healthcare/clinical_procedure_template#22-manage-procedure-consumables' target='_blank'>here</a>" + __(' to know more')

},
{
fieldname: 'medical_department',
title: __('Medical Department'),
description: __('You can also set the Medical Department for the template. After saving the document, an Item will automatically be created for billing this Clinical Procedure. You can then use this template while creating Clinical Procedures for Patients. Templates save you from filling up redundant data every single time. You can also create templates for other operations like Lab Tests, Therapy Sessions, etc.')
}
];

+ 286
- 0
healthcare/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json Vedi File

@@ -0,0 +1,286 @@
{
"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",
"link_existing_item",
"item",
"item_code",
"item_group",
"description",
"column_break_5",
"disabled",
"is_billable",
"rate",
"medical_department",
"pre_op_nursing_checklist_template",
"post_op_nursing_checklist_template",
"medical_coding_section",
"medical_code_standard",
"medical_code",
"consumables",
"consume_stock",
"items",
"sample_collection",
"sample",
"sample_uom",
"sample_qty",
"column_break_21",
"sample_details",
"change_in_item"
],
"fields": [
{
"fieldname": "template",
"fieldtype": "Data",
"in_global_search": 1,
"in_list_view": 1,
"label": "Template Name",
"reqd": 1,
"unique": 1
},
{
"depends_on": "eval:!doc.link_existing_item || !doc.__islocal",
"fieldname": "item_code",
"fieldtype": "Data",
"label": "Item Code",
"mandatory_depends_on": "eval:!doc.link_existing_item",
"read_only_depends_on": "eval: !doc.__islocal"
},
{
"fieldname": "item_group",
"fieldtype": "Link",
"ignore_user_permissions": 1,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Item Group",
"options": "Item Group",
"read_only_depends_on": "eval:doc.link_existing_item",
"reqd": 1
},
{
"fieldname": "medical_department",
"fieldtype": "Link",
"label": "Medical Department",
"options": "Medical Department"
},
{
"fieldname": "column_break_5",
"fieldtype": "Column Break"
},
{
"default": "0",
"depends_on": "eval:!doc.link_existing_item || !doc.__islocal;",
"fieldname": "is_billable",
"fieldtype": "Check",
"label": "Is Billable"
},
{
"depends_on": "eval:doc.is_billable && (!doc.link_existing_item || !doc.__islocal)",
"fieldname": "rate",
"fieldtype": "Float",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Rate",
"mandatory_depends_on": "eval:doc.is_billable && !doc.link_existing_item"
},
{
"fieldname": "description",
"fieldtype": "Small Text",
"ignore_xss_filter": 1,
"label": "Description",
"no_copy": 1,
"reqd": 1
},
{
"default": "0",
"fieldname": "consume_stock",
"fieldtype": "Check",
"label": "Allow Stock Consumption",
"search_index": 1
},
{
"fieldname": "consumables",
"fieldtype": "Section Break",
"label": "Consumables"
},
{
"depends_on": "eval:doc.consume_stock == 1",
"fieldname": "items",
"fieldtype": "Table",
"ignore_user_permissions": 1,
"label": "Items",
"options": "Clinical Procedure Item"
},
{
"collapsible": 1,
"fieldname": "sample_collection",
"fieldtype": "Section Break",
"label": "Sample Collection"
},
{
"fieldname": "sample",
"fieldtype": "Link",
"ignore_user_permissions": 1,
"label": "Sample",
"options": "Lab Test Sample"
},
{
"fetch_from": "sample.sample_uom",
"fieldname": "sample_uom",
"fieldtype": "Data",
"label": "Sample UOM",
"read_only": 1
},
{
"fieldname": "sample_qty",
"fieldtype": "Float",
"label": "Quantity"
},
{
"fieldname": "column_break_21",
"fieldtype": "Column Break"
},
{
"fieldname": "sample_details",
"fieldtype": "Small Text",
"ignore_xss_filter": 1,
"label": "Collection Details"
},
{
"default": "0",
"fieldname": "change_in_item",
"fieldtype": "Check",
"hidden": 1,
"label": "Change In Item",
"no_copy": 1,
"print_hide": 1,
"report_hide": 1
},
{
"default": "0",
"fieldname": "disabled",
"fieldtype": "Check",
"label": "Disabled"
},
{
"depends_on": "eval: !doc.__islocal || doc.link_existing_item",
"fieldname": "item",
"fieldtype": "Link",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Item",
"mandatory_depends_on": "eval:doc.link_existing_item",
"no_copy": 1,
"options": "Item",
"read_only_depends_on": "eval: !doc.__islocal"
},
{
"collapsible": 1,
"fieldname": "medical_coding_section",
"fieldtype": "Section Break",
"label": "Medical Coding"
},
{
"fieldname": "medical_code_standard",
"fieldtype": "Link",
"label": "Medical Code Standard",
"options": "Medical Code Standard"
},
{
"depends_on": "medical_code_standard",
"fieldname": "medical_code",
"fieldtype": "Link",
"label": "Medical Code",
"options": "Medical Code"
},
{
"fieldname": "pre_op_nursing_checklist_template",
"fieldtype": "Link",
"label": "Pre-op Nursing Checklist Template",
"options": "Nursing Checklist Template"
},
{
"fieldname": "post_op_nursing_checklist_template",
"fieldtype": "Link",
"label": "Post-op Nursing Checklist Template",
"options": "Nursing Checklist Template"
},
{
"default": "0",
"depends_on": "eval: doc.__islocal",
"fieldname": "link_existing_item",
"fieldtype": "Check",
"label": "Link existing Item"
}
],
"links": [],
"modified": "2022-06-22 06:42:56.910453",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Clinical Procedure Template",
"naming_rule": "By fieldname",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
},
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Healthcare Administrator",
"share": 1,
"write": 1
},
{
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Nursing User",
"share": 1
},
{
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Physician",
"share": 1,
"write": 1
}
],
"restrict_to_domain": "Healthcare",
"search_fields": "template",
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"title_field": "template",
"track_changes": 1,
"track_seen": 1
}

+ 149
- 0
healthcare/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py Vedi File

@@ -0,0 +1,149 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, earthians and contributors
# For license information, please see license.txt


import json

import frappe
from frappe import _
from frappe.model.document import Document
from frappe.model.rename_doc import rename_doc
from frappe.utils import today


class ClinicalProcedureTemplate(Document):
def before_insert(self):
if self.link_existing_item and self.item:
price_list = frappe.db.get_all(
"Item Price", {"item_code": self.item}, ["price_list_rate"], order_by="valid_from desc"
)
if price_list:
self.rate = price_list[0].get("price_list_rate")

def validate(self):
self.enable_disable_item()

def after_insert(self):
if not self.link_existing_item:
create_item_from_template(self)

def on_update(self):
if self.change_in_item:
update_item_and_item_price(self)

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)


@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 = doc.disabled
if doc.is_billable and not doc.disabled:
disabled = 0

uom = frappe.db.exists("UOM", "Unit") or frappe.db.get_single_value("Stock Settings", "stock_uom")
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": uom,
}
).insert(ignore_permissions=True, ignore_mandatory=True)

make_item_price(item.name, doc.rate)
doc.db_set("item", item.name)


def make_item_price(item, item_price):
price_list_name = frappe.db.get_value(
"Selling Settings", None, "selling_price_list"
) or 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,
"valid_from": today(),
}
).insert(ignore_permissions=True, ignore_mandatory=True)


@frappe.whitelist()
def change_item_code_from_template(item_code, doc):
doc = frappe._dict(json.loads(doc))

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


def update_item_and_item_price(doc):
if doc.is_billable and doc.item:
item_name = doc.lab_test_name if doc.get("doctype") == "Lab Test Template" else doc.template
rate = doc.lab_test_rate if doc.get("doctype") == "Lab Test Template" else doc.rate
item_group = doc.lab_test_group if doc.get("doctype") == "Lab Test Template" else doc.item_group

item_doc = frappe.get_doc("Item", {"item_code": doc.item})
item_doc.item_name = item_name
item_doc.item_group = item_group
item_doc.description = (
doc.description if doc.get("doctype") == "Clinical Procedure Template" else ""
)
item_doc.disabled = 0
item_doc.save(ignore_permissions=True)
if rate:
if not frappe.db.exists("Item Price", {"item_code": doc.item, "valid_from": today()}):
make_item_price(doc.item, rate)
else:
item_price = frappe.get_doc("Item Price", {"item_code": doc.item})
item_price.item_name = item_name
item_price.valid_from = today()
item_price.price_list_rate = rate
item_price.save()

elif not doc.is_billable and doc.item and not doc.link_existing_item:
frappe.db.set_value("Item", doc.item, "disabled", 1)

doc.db_set("change_in_item", 0)

+ 8
- 0
healthcare/healthcare/doctype/clinical_procedure_template/clinical_procedure_template_dashboard.py Vedi File

@@ -0,0 +1,8 @@
from frappe import _


def get_data():
return {
"fieldname": "procedure_template",
"transactions": [{"label": _("Consultations"), "items": ["Clinical Procedure"]}],
}

+ 10
- 0
healthcare/healthcare/doctype/clinical_procedure_template/test_clinical_procedure_template.py Vedi File

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, earthians and Contributors
# See license.txt


from frappe.tests.utils import FrappeTestCase


class TestClinicalProcedureTemplate(FrappeTestCase):
pass

+ 0
- 0
healthcare/healthcare/doctype/codification_table/__init__.py Vedi File


+ 56
- 0
healthcare/healthcare/doctype/codification_table/codification_table.json Vedi File

@@ -0,0 +1,56 @@
{
"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": [
{
"fieldname": "medical_code",
"fieldtype": "Link",
"ignore_user_permissions": 1,
"in_list_view": 1,
"label": "Medical Code",
"options": "Medical Code",
"reqd": 1
},
{
"fetch_from": "medical_code.code",
"fieldname": "code",
"fieldtype": "Data",
"ignore_xss_filter": 1,
"in_list_view": 1,
"label": "Code",
"read_only": 1
},
{
"fetch_from": "medical_code.description",
"fieldname": "description",
"fieldtype": "Small Text",
"ignore_xss_filter": 1,
"in_list_view": 1,
"label": "Description",
"read_only": 1
}
],
"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
}

+ 10
- 0
healthcare/healthcare/doctype/codification_table/codification_table.py Vedi File

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, InfluxERP
# For license information, please see license.txt


from frappe.model.document import Document


class CodificationTable(Document):
pass

+ 0
- 0
healthcare/healthcare/doctype/complaint/__init__.py Vedi File


+ 5
- 0
healthcare/healthcare/doctype/complaint/complaint.js Vedi File

@@ -0,0 +1,5 @@
// Copyright (c) 2017, InfluxERP
// For license information, please see license.txt

frappe.ui.form.on('Complaint', {
});

+ 116
- 0
healthcare/healthcare/doctype/complaint/complaint.json Vedi File

@@ -0,0 +1,116 @@
{
"allow_copy": 1,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:complaints",
"beta": 1,
"creation": "2017-02-15 12:25:28.045267",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "complaints",
"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": "Complaints",
"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
}
],
"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-10-05 11:18:42.017864",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Complaint",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 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,
"apply_user_permissions": 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
}
],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"restrict_to_domain": "Healthcare",
"search_fields": "complaints",
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "complaints",
"track_changes": 0,
"track_seen": 0
}

+ 10
- 0
healthcare/healthcare/doctype/complaint/complaint.py Vedi File

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, InfluxERP
# For license information, please see license.txt


from frappe.model.document import Document


class Complaint(Document):
pass

+ 10
- 0
healthcare/healthcare/doctype/complaint/test_complaint.py Vedi File

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, InfluxERP
# See license.txt


from frappe.tests.utils import FrappeTestCase


class TestComplaint(FrappeTestCase):
pass

+ 0
- 0
healthcare/healthcare/doctype/descriptive_test_result/__init__.py Vedi File


+ 74
- 0
healthcare/healthcare/doctype/descriptive_test_result/descriptive_test_result.json Vedi File

@@ -0,0 +1,74 @@
{
"actions": [],
"allow_copy": 1,
"beta": 1,
"creation": "2016-02-22 15:12:36.202380",
"doctype": "DocType",
"document_type": "Document",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"lab_test_particulars",
"result_value",
"allow_blank",
"template",
"require_result_value"
],
"fields": [
{
"fieldname": "lab_test_particulars",
"fieldtype": "Data",
"ignore_xss_filter": 1,
"in_list_view": 1,
"label": "Particulars",
"read_only": 1
},
{
"depends_on": "eval:doc.require_result_value == 1",
"fieldname": "result_value",
"fieldtype": "Small Text",
"ignore_xss_filter": 1,
"in_list_view": 1,
"label": "Value"
},
{
"fieldname": "template",
"fieldtype": "Link",
"hidden": 1,
"label": "Template",
"options": "Lab Test Template",
"print_hide": 1,
"report_hide": 1
},
{
"default": "0",
"fieldname": "require_result_value",
"fieldtype": "Check",
"hidden": 1,
"label": "Require Result Value",
"print_hide": 1,
"read_only": 1,
"report_hide": 1
},
{
"default": "1",
"fieldname": "allow_blank",
"fieldtype": "Check",
"label": "Allow Blank",
"print_hide": 1,
"read_only": 1,
"report_hide": 1
}
],
"istable": 1,
"links": [],
"modified": "2020-07-23 12:33:47.693065",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Descriptive Test Result",
"owner": "Administrator",
"permissions": [],
"restrict_to_domain": "Healthcare",
"sort_field": "modified",
"sort_order": "DESC"
}

+ 10
- 0
healthcare/healthcare/doctype/descriptive_test_result/descriptive_test_result.py Vedi File

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, ESS and contributors
# For license information, please see license.txt


from frappe.model.document import Document


class DescriptiveTestResult(Document):
pass

+ 0
- 0
healthcare/healthcare/doctype/descriptive_test_template/__init__.py Vedi File


+ 41
- 0
healthcare/healthcare/doctype/descriptive_test_template/descriptive_test_template.json Vedi File

@@ -0,0 +1,41 @@
{
"actions": [],
"allow_copy": 1,
"beta": 1,
"creation": "2016-02-22 16:12:12.394200",
"doctype": "DocType",
"document_type": "Setup",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"particulars",
"allow_blank"
],
"fields": [
{
"fieldname": "particulars",
"fieldtype": "Data",
"ignore_xss_filter": 1,
"in_list_view": 1,
"label": "Result Component"
},
{
"default": "0",
"fieldname": "allow_blank",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Allow Blank"
}
],
"istable": 1,
"links": [],
"modified": "2020-06-24 14:03:51.728863",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Descriptive Test Template",
"owner": "Administrator",
"permissions": [],
"restrict_to_domain": "Healthcare",
"sort_field": "modified",
"sort_order": "DESC"
}

+ 10
- 0
healthcare/healthcare/doctype/descriptive_test_template/descriptive_test_template.py Vedi File

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, ESS and contributors
# For license information, please see license.txt


from frappe.model.document import Document


class DescriptiveTestTemplate(Document):
pass

+ 0
- 0
healthcare/healthcare/doctype/diagnosis/__init__.py Vedi File


+ 5
- 0
healthcare/healthcare/doctype/diagnosis/diagnosis.js Vedi File

@@ -0,0 +1,5 @@
// Copyright (c) 2016, ESS LLP and contributors
// For license information, please see license.txt

frappe.ui.form.on('Diagnosis', {
});

+ 116
- 0
healthcare/healthcare/doctype/diagnosis/diagnosis.json Vedi File

@@ -0,0 +1,116 @@
{
"allow_copy": 1,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:diagnosis",
"beta": 1,
"creation": "2017-02-15 12:23:59.341108",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "diagnosis",
"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": "Diagnosis",
"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
}
],
"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-10-05 11:25:46.107435",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Diagnosis",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 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,
"apply_user_permissions": 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
}
],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"restrict_to_domain": "Healthcare",
"search_fields": "diagnosis",
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "diagnosis",
"track_changes": 1,
"track_seen": 0
}

+ 10
- 0
healthcare/healthcare/doctype/diagnosis/diagnosis.py Vedi File

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, ESS LLP and contributors
# For license information, please see license.txt


from frappe.model.document import Document


class Diagnosis(Document):
pass

+ 12
- 0
healthcare/healthcare/doctype/diagnosis/test_diagnosis.py Vedi File

@@ -0,0 +1,12 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, ESS LLP and Contributors
# See license.txt


from frappe.tests.utils import FrappeTestCase

# test_records = frappe.get_test_records('Diagnosis')


class TestDiagnosis(FrappeTestCase):
pass

+ 0
- 0
healthcare/healthcare/doctype/dosage_form/__init__.py Vedi File


+ 5
- 0
healthcare/healthcare/doctype/dosage_form/dosage_form.js Vedi File

@@ -0,0 +1,5 @@
// Copyright (c) 2017, ESS LLP and contributors
// For license information, please see license.txt

frappe.ui.form.on('Dosage Form', {
});

+ 114
- 0
healthcare/healthcare/doctype/dosage_form/dosage_form.json Vedi File

@@ -0,0 +1,114 @@
{
"allow_copy": 1,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:dosage_form",
"beta": 1,
"creation": "2017-04-08 12:04:33.987972",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "dosage_form",
"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": "Dosage Form",
"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
}
],
"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-10-05 11:24:57.888091",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Dosage Form",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 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,
"apply_user_permissions": 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
}
],
"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
}

+ 10
- 0
healthcare/healthcare/doctype/dosage_form/dosage_form.py Vedi File

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, ESS LLP and contributors
# For license information, please see license.txt


from frappe.model.document import Document


class DosageForm(Document):
pass

+ 10
- 0
healthcare/healthcare/doctype/dosage_form/test_dosage_form.py Vedi File

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, ESS LLP and Contributors
# See license.txt


from frappe.tests.utils import FrappeTestCase


class TestDosageForm(FrappeTestCase):
pass

+ 0
- 0
healthcare/healthcare/doctype/dosage_strength/__init__.py Vedi File


+ 102
- 0
healthcare/healthcare/doctype/dosage_strength/dosage_strength.json Vedi File

@@ -0,0 +1,102 @@
{
"allow_copy": 1,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 1,
"creation": "2017-02-14 15:40:14.385707",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "strength",
"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": "Strength",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "strength_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": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2017-08-31 14:11:59.874645",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Dosage Strength",
"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": 0,
"track_seen": 0
}

+ 10
- 0
healthcare/healthcare/doctype/dosage_strength/dosage_strength.py Vedi File

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, ESS LLP and contributors
# For license information, please see license.txt


from frappe.model.document import Document


class DosageStrength(Document):
pass

+ 0
- 0
healthcare/healthcare/doctype/drug_prescription/__init__.py Vedi File


Dato che sono stati cambiati molti file in questo diff, alcuni di essi non verranno mostrati

Caricamento…
Annulla
Salva