Merge remote-tracking branch 'origin/dev'

This commit is contained in:
Steve Nyemba 2021-01-12 15:56:21 -06:00
commit f25a5831c0
27 changed files with 2563 additions and 443 deletions

View File

@ -22,16 +22,26 @@ We wrote this frame to be used in both command line or as a library within in yo
pip install --upgrade git+https://hiplab.mc.vanderbilt.edu/git/lab/parse-edi.git
## Usage
**cli :**
1. signup to get parsing configuration
healthcare-io.py --signup <email> [--store <mongo|sqlite>]
2. parsing claims in a folder
The parser is driven by a configuration file that specifies fields to parse and how to parse them. You need by signing up, to get a copy of the configuration file.
healthcare-io.py --parse <claims|remits> --folder <path> [--batch <n>] [--resume]
healthcare-io.py --signup <email> [--store <mongo|sqlite>]
2. check version
Occasionally the attributes in the configuration file may change, This function will determine if there is a new version available.
healthcare-io.py --check-update
3. parsing data in a folder
The parser will recursively traverse a directory with claims and or remittances
healthcare-io.py --parse --folder <path> [--batch <n>] [--resume]
with :
--parse tells the engine what to parse claims or remits
@ -39,12 +49,42 @@ We wrote this frame to be used in both command line or as a library within in yo
--batch number of processes to spawn to parse the files
--resume tells the parser to resume parsing
if all files weren't processed or new files were added into the folder
3. dashboard
There is a built-in dashboard that has displays descriptive analytics in a web browser
healthcare-io.py --server <port> [--context <name>]
4. export data to a relational data-store
The parser will export data into other data-stores as a relational tables allowing users to construct views to support a variety of studies.
healthcare-io.py --export <835|837> --config <path-export.json>
with:
--config configuration to support data-store
The configuration file needed to implement export is modelled after the following template:
{
"provider":"<postgresql|redshift|mysql|mariadb>",
"db":"mydatabase",
[
"host":"server-name","port":5432,
"user":"me","password":"!@#z4qm",
"schema":"target-schema"
]
}
**parameters:**
provider postgresql,redshift,mysql or mariadb (supported providers)
db name of the database
**optional:**
schema name of the target schema. If not provided we will assume the default
host host of the database. If not provided assuming localhost
port port value of the database if not provided the default will be used
user database user name. If not provided we assume security settings to trust
password password of database user. If not set we assume security settings to trust
**Embedded in Code :**
The Healthcare/IO **parser** can be used within your code base as a library and handle storing data in a data store of choice

View File

@ -1,4 +1,8 @@
FROM ubuntu:bionic-20200403
#
# Let us create an image for healthcareio
# The image will contain the {X12} Parser and the
# FROM ubuntu:bionic-20200403
FROM ubuntu:focal
RUN ["apt","update","--fix-missing"]
RUN ["apt-get","upgrade","-y"]
@ -6,9 +10,22 @@ RUN ["apt-get","-y","install","apt-utils"]
RUN ["apt","update","--fix-missing"]
RUN ["apt-get","upgrade","-y"]
RUN ["apt-get","install","-y","sqlite3","sqlite3-pcre","libsqlite3-dev","python3-dev","python3","python3-pip","git","python3-virtualenv"]
RUN ["apt-get","install","-y","mongo","sqlite3","sqlite3-pcre","libsqlite3-dev","python3-dev","python3","python3-pip","git","python3-virtualenv","wget"]
#
#
RUN ["pip3","install","--upgrade","pip"]
# RUN ["pip3","install","git+https://healthcare.the-phi.com/git/code/parser.git","botocore"]
USER health-user
#
# This volume is where the data will be loaded from (otherwise it is assumed the user will have it in the container somehow)
#
VOLUME ["/data"]
#
# This is the port from which some degree of monitoring can/will happen
EXPOSE 80
# wget https://healthcareio.the-phi.com/git/code/parser.git/bootup.sh
COPY bootup.sh bootup.sh
ENTRYPOINT ["bash","-C"]
CMD ["bootup.sh"]
# VOLUME ["/home/health-user/healthcare-io/","/home-healthuser/.healthcareio"]
# RUN ["pip3","install","git+https://healthcareio.the-phi.com/git"]
# RUN ["pip3","install","git+https://healthcareio.the-phi.com/git"]

View File

@ -16,5 +16,9 @@ Usage :
"""
from healthcareio import analytics
from healthcareio import server
from healthcareio import export
import healthcareio.x12 as x12
import healthcareio.params as params
# from healthcareio import server

View File

@ -11,7 +11,7 @@ import transport
import matplotlib.pyplot as plt
import re, base64
# from weasyprint import HTML, CSS
COLORS = ["#f79256","#7dcfb6","#fbd1a2","#00b2ca","#1d4e89","#4682B4","#c5c3c6","#4c5c68","#1985a1","#f72585","#7209b7","#3a0ca3","#4361ee","#4cc9f0","#ff595e","#ffca3a","#8ac926","#1982c4","#6a4c93"]
COLORS = ["#fbd1a2","#00b2ca","#1d4e89","#4682B4","#c5c3c6","#4c5c68","#1985a1","#f72585","#7209b7","#3a0ca3","#4361ee","#4cc9f0","#ff595e","#ffca3a","#8ac926","#1982c4","#6a4c93"]
class stdev :
def __init__(self) :
self.values = []
@ -149,11 +149,16 @@ class Apex :
This class will format a data-frame to work with Apex charting engine
"""
@staticmethod
def apply(item):
def apply(item,theme={'mode':'light','palette':'palette6'}):
pointer = item['chart']['type']
if hasattr(Apex,pointer) :
pointer = getattr(Apex,pointer)
options = pointer(item)
if 'apex' in options and 'colors' in options['apex'] :
del options['apex']['colors']
if 'apex' in options :
options['apex']['theme'] = theme
options['responsive']= [
{
'breakpoint': 1,
@ -168,6 +173,18 @@ class Apex :
print ("Oops")
pass
@staticmethod
def radial(item):
df = item['data']
x = item['chart']['axis']['x']
y = item['chart']['axis']['y']
labels = df[y].tolist()
values = [float(np.round(value,2)) for value in df[x].tolist()]
chart = {"type":"radialBar","height":200}
option = {"chart":chart,"series":values,"labels":labels,"plotOptions":{"radialBar":{"hollow":{"size":"70%"}}}}
return {'apex':option}
@staticmethod
def scatter(item):
options = Apex.spline(item)
options['apex']['chart']['type'] = 'scatter'
@ -175,7 +192,7 @@ class Apex :
@staticmethod
def scalar(item):
_df = item['data']
print (_df)
name = _df.columns.tolist()[0]
value = _df[name].values.round(2)[0]
html = '<div class="scalar"><div class="value">:value</div><div class="label">:label</div></div>'
@ -235,16 +252,17 @@ class Apex :
@TODO: alias this with bar (!= column)
"""
df = item['data']
N = df.shape[0] if df.shape[0] < 10 else 10
axis = item['chart']['axis']
y = axis['y']
if type(y) == list :
y = y[0]
axis['x'] = [axis['x']] if type(axis['x']) != list else axis['x']
if not set(axis['x']) & set(df.columns.tolist()) :
print (set(axis['x']) & set(df.columns.tolist()))
print (axis['x'])
print (df.columns)
# if not set(axis['x']) & set(df.columns.tolist()) :
# print (set(axis['x']) & set(df.columns.tolist()))
# print (axis['x'])
# print (df.columns)
# df.columns = axis['x']
series = []
_min=_max = 0
@ -294,7 +312,6 @@ class Apex :
values are x-axis
"""
df = item['data']
if df.shape [0]> 1 :
y_cols,x_cols = item['chart']['axis']['y'],item['chart']['axis']['x']
labels = df[y_cols].values.tolist()
@ -302,10 +319,11 @@ class Apex :
values = df[x_cols].values.round(2).tolist()
else:
labels = [name.upper().replace('_',' ') for name in df.columns.tolist()]
df = df.astype(float)
values = df.values.round(2).tolist()[0] if df.shape[1] > 1 else df.values.round(2).tolist()
colors = COLORS[:len(values)]
options = {"series":values,"colors":colors,"labels":labels,"chart":{"type":"donut"},"plotOptions":{"pie":{"customScale":.8}},"legend":{"position":"right"}}
options = {"series":values,"colors":colors,"labels":labels,"dataLabels":{"enabled":True,"style":{"colors":["#000000"]},"dropShadow":{"enabled":False}},"chart":{"type":"donut","width":200},"plotOptions":{"pie":{"customScale":.9}},"legend":{"position":"right"}}
return {"apex":options}
pass
@ -329,43 +347,117 @@ class engine :
_args['type'] = 'mongo.MongoReader'
else:
_args['type'] = 'disk.SQLiteReader'
self.reader = transport.factory.instance(**_args)
self.store_config = _args ;
def filter (self,**args):
"""
type: claims or remits
filter optional identifier claims, procedures, taxonomy, ...
"""
_m = {'claim':'837','claims':'837','remits':'835','remit':'835'}
table = _m[ args['type']]
_analytics = self.info[table]
if 'index' in args :
index = int(args['index'])
_analytics = [_analytics[index]]
_info = list(_analytics) #if 'filter' not in args else [item for item in analytics if args['filter'] == item['id']]
# conn = lite.connect(self.store_config['args']['path'],isolation_level=None)
# conn.create_aggregate("stdev",1,stdev)
DB_TYPE = 'mongo' if (type(self.reader) == transport.mongo.MongoReader) else 'sql'
if DB_TYPE == 'mongo' :
self.store_config['args']['doc'] = args['type']
self.reader = transport.factory.instance(**self.store_config)
r = []
for row in _info :
pipeline = row['pipeline']
index = 0
for item in pipeline:
if not item[DB_TYPE] :
continue
query = {DB_TYPE:item[DB_TYPE]}
df = pd.DataFrame(self.reader.read(**query)) #item)
df = df.fillna('N/A')
# item['data'] = df
chart = item['chart']
pipe = {"data":df,"chart":chart}
for key in list(item.keys()) :
if key not in ["chart","data","mongo","sql","couch"] :
pipe[key] = item[key]
r.append(pipe)
self.reader.close()
return {"id":_info[0]['id'],'pipeline':r}
def apply (self,**args) :
"""
type: claims or remits
filter optional identifier claims, procedures, taxonomy, ...
"""
_m = {'claim':'837','claims':'837','remits':'835','remit':'835'}
# key = '837' if args['type'] == 'claims' else '835'
table = _m[ args['type']]
analytics = self.info[table]
_analytics = self.info[table]
if 'index' in args :
index = int(args['index'])
analytics = [analytics[index]]
_analytics = [_analytics[index]]
_info = list(analytics) if 'filter' not in args else [item for item in analytics if args['filter'] == item['id']]
_info = list(_analytics) if 'filter' not in args else [item for item in analytics if args['filter'] == item['id']]
# conn = lite.connect(self.store_config['args']['path'],isolation_level=None)
# conn.create_aggregate("stdev",1,stdev)
DB_TYPE = 'mongo' if (type(self.reader) == transport.mongo.MongoReader) else 'sql'
#
# @TODO: Find a better way to handle database variance
#
# DB_TYPE = 'mongo' if (type(self.reader) == transport.mongo.MongoReader) else 'sql'
if 'mongo' in self.store_config['type'] :
DB_TYPE='mongo'
else:
DB_TYPE='sql'
self.store_config['args']['table'] = args['type']
self.reader = transport.factory.instance(**self.store_config)
r = []
for row in _info :
for item in row['pipeline'] :
pipeline = row['pipeline']
index = 0
for item in pipeline:
# item['data'] = pd.read_sql(item['sql'],conn)
query = {DB_TYPE:item[DB_TYPE]}
item['data'] = self.reader.read(**item)
# query = {DB_TYPE:item[DB_TYPE]}
query = item[DB_TYPE]
if not query :
continue
if DB_TYPE == 'sql' :
query = {"sql":query}
item['data'] = self.reader.read(**query) #item)
if 'serialize' in args :
item['data'] = json.dumps(item['data'].to_dict(orient='record')) if type(item['data']) == pd.DataFrame else item['data']
# item['data'] = json.dumps(item['data'].to_dict(orient='record')) if type(item['data']) == pd.DataFrame else item['data']
item['data'] = json.dumps(item['data'].to_dict('record')) if type(item['data']) == pd.DataFrame else item['data']
else:
item['data'] = (pd.DataFrame(item['data']))
pipeline[index] = item
index += 1
#
#
row['pipeline']= pipeline
# if 'info' in item:
# item['info'] = item['info'].replace(":rows",str(item["data"].shape[0]))
# conn.close()
self.reader.close()
return _info
def _html(self,item) :

View File

@ -0,0 +1,37 @@
#
# Let us create an image for healthcareio
# The image will contain the {X12} Parser and the
# FROM ubuntu:bionic-20200403
FROM ubuntu:focal
RUN ["apt-get","update","--fix-missing"]
RUN ["apt-get","upgrade","-y"]
RUN ["apt-get","-y","install","apt-utils"]
RUN ["apt-get","update","--fix-missing"]
RUN ["apt-get","upgrade","-y"]
RUN ["apt-get","install","-y","mongodb","sqlite3","sqlite3-pcre","libsqlite3-dev","python3-dev","python3","python3-pip","git","python3-virtualenv","wget"]
#
#
RUN ["pip3","install","--upgrade","pip"]
RUN ["pip3","install","numpy","pandas","git+https://dev.the-phi.com/git/steve/data-transport","botocore","matplotlib"]
# RUN ["pip3","install","git+https://healthcare.the-phi.com/git/code/parser.git","botocore"]
# RUN ["useradd", "-ms", "/bin/bash", "health-user"]
# USER health-user
#
# This volume is where the data will be loaded from (otherwise it is assumed the user will have it in the container somehow)
#
VOLUME ["/data","/app/healthcareio"]
WORKDIR /app
ENV PYTHONPATH="/app"
#
# This is the port from which some degree of monitoring can/will happen
EXPOSE 80
EXPOSE 27017
# wget https://healthcareio.the-phi.com/git/code/parser.git/bootup.sh
COPY bootup.sh bootup.sh
ENTRYPOINT ["bash","-C"]
CMD ["bootup.sh"]
# VOLUME ["/home/health-user/healthcare-io/","/home-healthuser/.healthcareio"]
# RUN ["pip3","install","git+https://healthcareio.the-phi.com/git"]

View File

@ -0,0 +1,10 @@
set -e
/etc/init.d/mongodb start
cd /app
export
export PYTHONPATH=$PWD
ls
# python3 healthcareio/healthcare-io.py --signup $EMAIL --store mongo
# python3 healthcareio/healthcare-io.py --analytics --port 80 --debug
bash

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@ -0,0 +1,314 @@
<?xml version="1.0" encoding="UTF-8"?>
<XMI xmi.version="1.2" timestamp="2021-01-11T11:53:03" xmlns:UML="http://schema.omg.org/spec/UML/1.4" verified="false">
<XMI.header>
<XMI.documentation>
<XMI.exporter>umbrello uml modeller http://umbrello.kde.org</XMI.exporter>
<XMI.exporterVersion>1.6.17</XMI.exporterVersion>
<XMI.exporterEncoding>UnicodeUTF8</XMI.exporterEncoding>
</XMI.documentation>
<XMI.metamodel xmi.version="1.4" xmi.name="UML" href="UML.xml"/>
</XMI.header>
<XMI.content>
<UML:Model isAbstract="false" isRoot="false" name="UML Model" isLeaf="false" isSpecification="false" xmi.id="m1">
<UML:Namespace.ownedElement>
<UML:Stereotype isAbstract="false" isRoot="false" name="folder" isLeaf="false" visibility="public" isSpecification="false" xmi.id="folder" namespace="m1"/>
<UML:Model isAbstract="false" isRoot="false" name="Logical View" isLeaf="false" visibility="public" isSpecification="false" xmi.id="Logical_View" namespace="m1">
<UML:Namespace.ownedElement>
<UML:Package isAbstract="false" isRoot="false" name="Datatypes" isLeaf="false" visibility="public" stereotype="folder" isSpecification="false" xmi.id="Datatypes" namespace="Logical_View">
<UML:Namespace.ownedElement>
<UML:DataType isAbstract="false" isRoot="false" name="char" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uabvhj07enGME" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="int" isLeaf="false" visibility="public" isSpecification="false" xmi.id="u4OxDbpjlH3pe" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="float" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uDJRPxwaZX3V7" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="double" isLeaf="false" visibility="public" isSpecification="false" xmi.id="usBQivEzmQ1BW" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="bool" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uwRCbX5F7jgLF" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="string" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uzDhYR9iUxXR6" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="unsigned char" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uFh4LzRYE3f5n" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="signed char" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uWGlDG1tsuigz" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="unsigned int" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uCRFY3OMvmsTh" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="signed int" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uzkXa9SjrJK3C" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="short int" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uHr88gSJngOwQ" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="unsigned short int" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uMFI3J7IsMqdx" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="signed short int" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uHnTLssRNvwe9" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="long int" isLeaf="false" visibility="public" isSpecification="false" xmi.id="udr0tadLTTAWz" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="signed long int" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uGiRQT4nooVd3" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="unsigned long int" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uXN2ZkDRs26FV" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="long double" isLeaf="false" visibility="public" isSpecification="false" xmi.id="ueN3MSvcxioDm" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="wchar_t" isLeaf="false" visibility="public" isSpecification="false" xmi.id="u3oTW1v02tom1" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="bigint" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uhsHrB8csHO10" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="bigserial" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uivybGgIE3bD0" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="bit" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uWWi8ci3eh65i" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="bit varying" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uqpjG9tkWEa7X" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="boolean" isLeaf="false" visibility="public" isSpecification="false" xmi.id="u5TSvGJ0WXtUp" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="box" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uGDbLeVMULJkk" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="bytea" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uLGmbFVmIZR5K" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="character varying" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uSnvPt02S7tvb" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="character" isLeaf="false" visibility="public" isSpecification="false" xmi.id="ukmjXUC40LtU7" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="cidr" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uz3Al8mzoS0I3" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="circle" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uyHfbIHPXILpB" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="date" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uL5DOPBGjUyyC" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="decimal" isLeaf="false" visibility="public" isSpecification="false" xmi.id="u6MI7pVV7hXsf" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="double precision" isLeaf="false" visibility="public" isSpecification="false" xmi.id="ujgGh0hthNOjx" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="inet" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uKX78NObRE1fe" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="integer" isLeaf="false" visibility="public" isSpecification="false" xmi.id="ulzNk0Rb91myv" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="interval" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uI220TA6Z0j6n" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="line" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uDrG5vcusdKBM" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="lseg" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uCgYfO6iac2jN" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="macaddr" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uxSn0sOl0rdv1" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="money" isLeaf="false" visibility="public" isSpecification="false" xmi.id="unOpNjlDqyBUV" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="numeric" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uOGQO1PzHG9jT" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="path" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uIYX1EziKvxte" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="point" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uB5Z9Av67TQfu" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="polygon" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uclB4l6uHrYXp" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="real" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uvDJ2b98uJr2k" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="serial" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uoRs9Jh7Jejo2" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="smallint" isLeaf="false" visibility="public" isSpecification="false" xmi.id="u0Uu6RLk1nAgq" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="time without time zone" isLeaf="false" visibility="public" isSpecification="false" xmi.id="u85nOph4JKwlg" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="time with time zone" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uL9aNTx5gdrZz" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="timestamp without time zone" isLeaf="false" visibility="public" isSpecification="false" xmi.id="u4qKd0QA9rWNf" namespace="Datatypes"/>
<UML:DataType isAbstract="false" isRoot="false" name="timestamp with time zone" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uOTQbnbs1N3TF" namespace="Datatypes"/>
</UML:Namespace.ownedElement>
</UML:Package>
</UML:Namespace.ownedElement>
<XMI.extension xmi.extender="umbrello">
<diagrams resolution="96">
<diagram xmi.id="u8KOkLitCdEg4" showattsig="1" localid="-1" snapcsgrid="0" documentation="" name="class diagram" snapgrid="0" showattribassocs="1" isopen="1" linecolor="#ff0000" linewidth="0" showopsig="1" snapy="25" usefillcolor="1" type="1" canvasheight="0" showatts="1" griddotcolor="#d3d3d3" snapx="25" zoom="100" fillcolor="#ffff00" showstereotype="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" textcolor="#000000" showops="1" showpubliconly="0" showscope="1" canvaswidth="0" backgroundcolor="#ffffff" showpackage="1" showgrid="0">
<widgets/>
<messages/>
<associations/>
</diagram>
</diagrams>
</XMI.extension>
</UML:Model>
<UML:Model isAbstract="false" isRoot="false" name="Use Case View" isLeaf="false" visibility="public" isSpecification="false" xmi.id="Use_Case_View" namespace="m1">
<UML:Namespace.ownedElement/>
</UML:Model>
<UML:Model isAbstract="false" isRoot="false" name="Component View" isLeaf="false" visibility="public" isSpecification="false" xmi.id="Component_View" namespace="m1">
<UML:Namespace.ownedElement/>
</UML:Model>
<UML:Model isAbstract="false" isRoot="false" name="Deployment View" isLeaf="false" visibility="public" isSpecification="false" xmi.id="Deployment_View" namespace="m1">
<UML:Namespace.ownedElement/>
</UML:Model>
<UML:Model isAbstract="false" isRoot="false" name="Entity Relationship Model" isLeaf="false" visibility="public" isSpecification="false" xmi.id="Entity_Relationship_Model" namespace="m1">
<UML:Namespace.ownedElement>
<UML:Entity isAbstract="false" isRoot="false" name="adjustments" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uIt8r5rl1o40g" namespace="Entity_Relationship_Model">
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="claim_id" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uSYVzSUI013SA" namespace="uIt8r5rl1o40g" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="amount" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uTpfrtFZpRhat" namespace="uIt8r5rl1o40g" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="reason" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="ukqfwxa6LykJ0" namespace="uIt8r5rl1o40g" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="quantity" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="u588PxOwyWVln" namespace="uIt8r5rl1o40g" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="_index" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uFD7jRw8vwz8o" namespace="uIt8r5rl1o40g" type="uSnvPt02S7tvb"/>
</UML:Entity>
<UML:Entity isAbstract="false" isRoot="false" name="claims" isLeaf="false" visibility="public" isSpecification="false" xmi.id="u0o6nLeO0fEm7" namespace="Entity_Relationship_Model">
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="claim_id" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uYDfK8VkY0Uex" namespace="u0o6nLeO0fEm7" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="claim_amount" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="un3xoNxajJ2xm" namespace="u0o6nLeO0fEm7" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="place_of_service" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uwUPYbIyt5p6d" namespace="u0o6nLeO0fEm7" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="is_delayed" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="u74xYiT4G5wyL" namespace="u0o6nLeO0fEm7" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="patient_dob" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="ulgSeuvbWb2IS" namespace="u0o6nLeO0fEm7" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="patient_gender" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="ue7HQl68mupvi" namespace="u0o6nLeO0fEm7" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="provider_code" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="u7ACwVQiy9E9Z" namespace="u0o6nLeO0fEm7" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="provider_ref_id_code" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uiZCcx2if32Rz" namespace="u0o6nLeO0fEm7" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="provider_ref_id" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="u6YddgnfmpAlc" namespace="u0o6nLeO0fEm7" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="receiver_id" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uogvUuoceENSP" namespace="u0o6nLeO0fEm7" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="claim_type" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="udh4izR25tLXk" namespace="u0o6nLeO0fEm7" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="submitted_date" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uNawwAMUkVRCI" namespace="u0o6nLeO0fEm7" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="submitted_time" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uRjR66XIKc4Cj" namespace="u0o6nLeO0fEm7" type="uSnvPt02S7tvb"/>
</UML:Entity>
<UML:Entity isAbstract="false" isRoot="false" name="dates" isLeaf="false" visibility="public" isSpecification="false" xmi.id="u9jx6NrYMk8ba" namespace="Entity_Relationship_Model">
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="claim_id" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uOFiCH5hs2CqD" namespace="u9jx6NrYMk8ba" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="date_value" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uWlHRTJczp2hP" namespace="u9jx6NrYMk8ba" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="date_type" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uJ3UETdwbO2Ig" namespace="u9jx6NrYMk8ba" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="_index" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uDgHTOeq61MN6" namespace="u9jx6NrYMk8ba" type="uSnvPt02S7tvb"/>
</UML:Entity>
<UML:Entity isAbstract="false" isRoot="false" name="diagnosis" isLeaf="false" visibility="public" isSpecification="false" xmi.id="u8PmJ0kOURyJH" namespace="Entity_Relationship_Model">
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="claim_id" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uO3lWqTMmrG6a" namespace="u8PmJ0kOURyJH" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="code" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uFe9gE8wNmF3K" namespace="u8PmJ0kOURyJH" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="type" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uyHg48x5zNXfx" namespace="u8PmJ0kOURyJH" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="_index" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uxk7Kdk2zHUiA" namespace="u8PmJ0kOURyJH" type="uSnvPt02S7tvb"/>
</UML:Entity>
<UML:Entity isAbstract="false" isRoot="false" name="insurance" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uryWFOwX9Hwnx" namespace="Entity_Relationship_Model">
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="claim_id" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uRBVaj3Qzg9x6" namespace="uryWFOwX9Hwnx" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="vendor" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="ud6f1Wq2fcILc" namespace="uryWFOwX9Hwnx" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="type" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uoMTq1S9lomkk" namespace="uryWFOwX9Hwnx" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="_index" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uhptNu9fqya8L" namespace="uryWFOwX9Hwnx" type="uSnvPt02S7tvb"/>
</UML:Entity>
<UML:Entity isAbstract="false" isRoot="false" name="payer_payment" isLeaf="false" visibility="public" isSpecification="false" xmi.id="urfdKBRGTHsvD" namespace="Entity_Relationship_Model">
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="claim_id" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uQoUZNnAPQtkc" namespace="urfdKBRGTHsvD" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="payer_id" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uDCgrCiBo3ofU" namespace="urfdKBRGTHsvD" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="amount_paid" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uqE70vCYpR39d" namespace="urfdKBRGTHsvD" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="type" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="utcVCqg6Ujm0K" namespace="urfdKBRGTHsvD" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="code" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uchV31XAlL5zV" namespace="urfdKBRGTHsvD" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="_index" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="u9JcqdgWdfAr7" namespace="urfdKBRGTHsvD" type="uSnvPt02S7tvb"/>
</UML:Entity>
<UML:Entity isAbstract="false" isRoot="false" name="payments" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uqcoZhRnX5ofD" namespace="Entity_Relationship_Model">
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="claim_id" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="umeVf4SSnodg6" namespace="uqcoZhRnX5ofD" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="amount" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="u7QSbdxKaVCfZ" namespace="uqcoZhRnX5ofD" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="qualifier" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="ubC1rdi8Tsfqz" namespace="uqcoZhRnX5ofD" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="_index" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uC6IVjw3XYT2f" namespace="uqcoZhRnX5ofD" type="uSnvPt02S7tvb"/>
</UML:Entity>
<UML:Entity isAbstract="false" isRoot="false" name="procedures" isLeaf="false" visibility="public" isSpecification="false" xmi.id="uzBUSd4zzXvR9" namespace="Entity_Relationship_Model">
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="claim_id" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="um1KvytxUVkEL" namespace="uzBUSd4zzXvR9" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="code" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uqr4qRy9YDMZv" namespace="uzBUSd4zzXvR9" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="service_id" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uCkrP7xWJJ8UD" namespace="uzBUSd4zzXvR9" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="quantity" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uPcRikSKl2zqO" namespace="uzBUSd4zzXvR9" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="unit" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="u0hNz09sDwFYQ" namespace="uzBUSd4zzXvR9" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="amount" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="ux0JFk7sWlVm4" namespace="uzBUSd4zzXvR9" type="uSnvPt02S7tvb"/>
<UML:EntityAttribute isAbstract="false" dbindex_type="1100" isRoot="false" auto_increment="0" name="_index" isLeaf="false" values="125" attributes="" visibility="public" initialValue="" isSpecification="false" allow_null="1" xmi.id="uRoHyMxDDc7FO" namespace="uzBUSd4zzXvR9" type="uSnvPt02S7tvb"/>
</UML:Entity>
</UML:Namespace.ownedElement>
<XMI.extension xmi.extender="umbrello">
<diagrams resolution="96">
<diagram xmi.id="u1KHlJny82WhH" showattsig="1" localid="-1" snapcsgrid="0" documentation="" name="claims-sql" snapgrid="1" showattribassocs="1" isopen="1" linecolor="#000000" linewidth="0" showopsig="1" snapy="25" usefillcolor="0" type="9" canvasheight="427" showatts="1" griddotcolor="#d3d3d3" snapx="25" zoom="100" fillcolor="#ffff00" showstereotype="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" textcolor="#000000" showops="1" showpubliconly="0" showscope="1" canvaswidth="1126" backgroundcolor="#ffffff" showpackage="1" showgrid="0">
<widgets>
<entitywidget xmi.id="u9jx6NrYMk8ba" localid="uQmpvyqvHokUk" height="75" usesdiagramusefillcolor="0" linecolor="#000000" linewidth="0" y="-575" usefillcolor="0" isinstance="0" x="-2250" showattsigs="1" fillcolor="#ffff00" showstereotype="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" textcolor="#000000" autoresize="1" usesdiagramfillcolor="0" width="236"/>
<entitywidget xmi.id="u0o6nLeO0fEm7" localid="uRYkAokLx9ZQj" height="201" usesdiagramusefillcolor="0" linecolor="#000000" linewidth="0" y="-575" usefillcolor="0" isinstance="0" x="-1975" showattsigs="1" fillcolor="#ffff00" showstereotype="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" textcolor="#000000" autoresize="0" usesdiagramfillcolor="0" width="302"/>
<floatingtext xmi.id="uDemX08IckkEy" role="700" localid="uNo8r8g2BuJ3G" posttext="" height="35" usesdiagramusefillcolor="0" linecolor="#000000" linewidth="0" text="837 CLAIMS" y="-650" usefillcolor="0" isinstance="0" x="-2500" fillcolor="#ffff00" showstereotype="1" font="Sans Serif,20,-1,5,50,0,0,0,0,0" textcolor="#000000" autoresize="1" usesdiagramfillcolor="0" pretext="" width="169"/>
<entitywidget xmi.id="uryWFOwX9Hwnx" localid="umAk5ifZJ1kRl" height="75" usesdiagramusefillcolor="0" linecolor="#000000" linewidth="0" y="-375" usefillcolor="0" isinstance="0" x="-2250" showattsigs="1" fillcolor="#ffff00" showstereotype="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" textcolor="#000000" autoresize="0" usesdiagramfillcolor="0" width="238"/>
<entitywidget xmi.id="u8PmJ0kOURyJH" localid="ueg6EQdGyk81X" height="79" usesdiagramusefillcolor="0" linecolor="#000000" linewidth="0" y="-475" usefillcolor="0" isinstance="0" x="-2250" showattsigs="1" fillcolor="#ffff00" showstereotype="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" textcolor="#000000" autoresize="0" usesdiagramfillcolor="0" width="238"/>
<entitywidget xmi.id="uqcoZhRnX5ofD" localid="uGrVEdAPjRMja" height="100" usesdiagramusefillcolor="0" linecolor="#000000" linewidth="0" y="-325" usefillcolor="0" isinstance="0" x="-1625" showattsigs="0" fillcolor="#ffff00" showstereotype="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" textcolor="#000000" autoresize="0" usesdiagramfillcolor="0" width="251"/>
<entitywidget xmi.id="urfdKBRGTHsvD" localid="usicGhIAq9f7L" height="103" usesdiagramusefillcolor="0" linecolor="#000000" linewidth="0" y="-450" usefillcolor="0" isinstance="0" x="-1625" showattsigs="1" fillcolor="#ffff00" showstereotype="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" textcolor="#000000" autoresize="1" usesdiagramfillcolor="0" width="250"/>
<entitywidget xmi.id="uIt8r5rl1o40g" localid="ud80YBCGjoc8n" height="96" usesdiagramusefillcolor="0" linecolor="#000000" linewidth="0" y="-575" usefillcolor="0" isinstance="0" x="-1625" showattsigs="1" fillcolor="#ffff00" showstereotype="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" textcolor="#000000" autoresize="0" usesdiagramfillcolor="0" width="251"/>
<entitywidget xmi.id="uzBUSd4zzXvR9" localid="u7tNjpPKWJoGd" height="127" usesdiagramusefillcolor="0" linecolor="#000000" linewidth="0" y="-350" usefillcolor="0" isinstance="0" x="-1975" showattsigs="0" fillcolor="#ffff00" showstereotype="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" textcolor="#000000" autoresize="0" usesdiagramfillcolor="0" width="302"/>
</widgets>
<messages/>
<associations/>
</diagram>
</diagrams>
</XMI.extension>
</UML:Model>
</UML:Namespace.ownedElement>
</UML:Model>
</XMI.content>
<XMI.extensions xmi.extender="umbrello">
<docsettings documentation="" viewid="u1KHlJny82WhH" uniqueid="uinb8VTgboe7o"/>
<listview>
<listitem id="Views" open="1" type="800">
<listitem id="Component_View" open="1" type="821"/>
<listitem id="Deployment_View" open="1" type="827"/>
<listitem id="Entity_Relationship_Model" open="1" type="836">
<listitem id="uIt8r5rl1o40g" open="0" type="832">
<listitem id="uFD7jRw8vwz8o" open="0" type="833"/>
<listitem id="uTpfrtFZpRhat" open="0" type="833"/>
<listitem id="uSYVzSUI013SA" open="0" type="833"/>
<listitem id="u588PxOwyWVln" open="0" type="833"/>
<listitem id="ukqfwxa6LykJ0" open="0" type="833"/>
</listitem>
<listitem id="u0o6nLeO0fEm7" open="0" type="832">
<listitem id="un3xoNxajJ2xm" open="0" type="833"/>
<listitem id="uYDfK8VkY0Uex" open="0" type="833"/>
<listitem id="udh4izR25tLXk" open="0" type="833"/>
<listitem id="u74xYiT4G5wyL" open="0" type="833"/>
<listitem id="ulgSeuvbWb2IS" open="0" type="833"/>
<listitem id="ue7HQl68mupvi" open="0" type="833"/>
<listitem id="uwUPYbIyt5p6d" open="0" type="833"/>
<listitem id="u7ACwVQiy9E9Z" open="0" type="833"/>
<listitem id="u6YddgnfmpAlc" open="0" type="833"/>
<listitem id="uiZCcx2if32Rz" open="0" type="833"/>
<listitem id="uogvUuoceENSP" open="0" type="833"/>
<listitem id="uNawwAMUkVRCI" open="0" type="833"/>
<listitem id="uRjR66XIKc4Cj" open="0" type="833"/>
</listitem>
<listitem id="u1KHlJny82WhH" open="0" label="claims-sql" type="834"/>
<listitem id="u9jx6NrYMk8ba" open="0" type="832">
<listitem id="uDgHTOeq61MN6" open="0" type="833"/>
<listitem id="uOFiCH5hs2CqD" open="0" type="833"/>
<listitem id="uJ3UETdwbO2Ig" open="0" type="833"/>
<listitem id="uWlHRTJczp2hP" open="0" type="833"/>
</listitem>
<listitem id="u8PmJ0kOURyJH" open="0" type="832">
<listitem id="uxk7Kdk2zHUiA" open="0" type="833"/>
<listitem id="uO3lWqTMmrG6a" open="0" type="833"/>
<listitem id="uFe9gE8wNmF3K" open="0" type="833"/>
<listitem id="uyHg48x5zNXfx" open="0" type="833"/>
</listitem>
<listitem id="uryWFOwX9Hwnx" open="0" type="832">
<listitem id="uhptNu9fqya8L" open="0" type="833"/>
<listitem id="uRBVaj3Qzg9x6" open="0" type="833"/>
<listitem id="uoMTq1S9lomkk" open="0" type="833"/>
<listitem id="ud6f1Wq2fcILc" open="0" type="833"/>
</listitem>
<listitem id="urfdKBRGTHsvD" open="0" type="832">
<listitem id="u9JcqdgWdfAr7" open="0" type="833"/>
<listitem id="uqE70vCYpR39d" open="0" type="833"/>
<listitem id="uQoUZNnAPQtkc" open="0" type="833"/>
<listitem id="uchV31XAlL5zV" open="0" type="833"/>
<listitem id="uDCgrCiBo3ofU" open="0" type="833"/>
<listitem id="utcVCqg6Ujm0K" open="0" type="833"/>
</listitem>
<listitem id="uqcoZhRnX5ofD" open="0" type="832">
<listitem id="uC6IVjw3XYT2f" open="0" type="833"/>
<listitem id="u7QSbdxKaVCfZ" open="0" type="833"/>
<listitem id="umeVf4SSnodg6" open="0" type="833"/>
<listitem id="ubC1rdi8Tsfqz" open="0" type="833"/>
</listitem>
<listitem id="uzBUSd4zzXvR9" open="0" type="832">
<listitem id="uRoHyMxDDc7FO" open="0" type="833"/>
<listitem id="ux0JFk7sWlVm4" open="0" type="833"/>
<listitem id="um1KvytxUVkEL" open="0" type="833"/>
<listitem id="uqr4qRy9YDMZv" open="0" type="833"/>
<listitem id="uPcRikSKl2zqO" open="0" type="833"/>
<listitem id="uCkrP7xWJJ8UD" open="0" type="833"/>
<listitem id="u0hNz09sDwFYQ" open="0" type="833"/>
</listitem>
</listitem>
<listitem id="Logical_View" open="1" type="801">
<listitem id="u8KOkLitCdEg4" open="0" label="class diagram" type="807"/>
<listitem id="Datatypes" open="0" type="830">
<listitem id="uhsHrB8csHO10" open="1" type="829"/>
<listitem id="uivybGgIE3bD0" open="1" type="829"/>
<listitem id="uWWi8ci3eh65i" open="1" type="829"/>
<listitem id="uqpjG9tkWEa7X" open="1" type="829"/>
<listitem id="uwRCbX5F7jgLF" open="0" type="829"/>
<listitem id="u5TSvGJ0WXtUp" open="1" type="829"/>
<listitem id="uGDbLeVMULJkk" open="1" type="829"/>
<listitem id="uLGmbFVmIZR5K" open="1" type="829"/>
<listitem id="uabvhj07enGME" open="0" type="829"/>
<listitem id="ukmjXUC40LtU7" open="1" type="829"/>
<listitem id="uSnvPt02S7tvb" open="1" type="829"/>
<listitem id="uz3Al8mzoS0I3" open="1" type="829"/>
<listitem id="uyHfbIHPXILpB" open="1" type="829"/>
<listitem id="uL5DOPBGjUyyC" open="1" type="829"/>
<listitem id="u6MI7pVV7hXsf" open="1" type="829"/>
<listitem id="usBQivEzmQ1BW" open="0" type="829"/>
<listitem id="ujgGh0hthNOjx" open="1" type="829"/>
<listitem id="uDJRPxwaZX3V7" open="0" type="829"/>
<listitem id="uKX78NObRE1fe" open="1" type="829"/>
<listitem id="u4OxDbpjlH3pe" open="0" type="829"/>
<listitem id="ulzNk0Rb91myv" open="1" type="829"/>
<listitem id="uI220TA6Z0j6n" open="1" type="829"/>
<listitem id="uDrG5vcusdKBM" open="1" type="829"/>
<listitem id="ueN3MSvcxioDm" open="0" type="829"/>
<listitem id="udr0tadLTTAWz" open="0" type="829"/>
<listitem id="uCgYfO6iac2jN" open="1" type="829"/>
<listitem id="uxSn0sOl0rdv1" open="1" type="829"/>
<listitem id="unOpNjlDqyBUV" open="1" type="829"/>
<listitem id="uOGQO1PzHG9jT" open="1" type="829"/>
<listitem id="uIYX1EziKvxte" open="1" type="829"/>
<listitem id="uB5Z9Av67TQfu" open="1" type="829"/>
<listitem id="uclB4l6uHrYXp" open="1" type="829"/>
<listitem id="uvDJ2b98uJr2k" open="1" type="829"/>
<listitem id="uoRs9Jh7Jejo2" open="1" type="829"/>
<listitem id="uHr88gSJngOwQ" open="0" type="829"/>
<listitem id="uWGlDG1tsuigz" open="0" type="829"/>
<listitem id="uzkXa9SjrJK3C" open="0" type="829"/>
<listitem id="uGiRQT4nooVd3" open="0" type="829"/>
<listitem id="uHnTLssRNvwe9" open="0" type="829"/>
<listitem id="u0Uu6RLk1nAgq" open="1" type="829"/>
<listitem id="uzDhYR9iUxXR6" open="0" type="829"/>
<listitem id="uL9aNTx5gdrZz" open="1" type="829"/>
<listitem id="u85nOph4JKwlg" open="1" type="829"/>
<listitem id="uOTQbnbs1N3TF" open="1" type="829"/>
<listitem id="u4qKd0QA9rWNf" open="1" type="829"/>
<listitem id="uFh4LzRYE3f5n" open="0" type="829"/>
<listitem id="uCRFY3OMvmsTh" open="0" type="829"/>
<listitem id="uXN2ZkDRs26FV" open="0" type="829"/>
<listitem id="uMFI3J7IsMqdx" open="0" type="829"/>
<listitem id="u3oTW1v02tom1" open="0" type="829"/>
</listitem>
</listitem>
<listitem id="Use_Case_View" open="1" type="802"/>
</listitem>
</listview>
<codegeneration>
<codegenerator language="PostgreSQL"/>
</codegeneration>
</XMI.extensions>
</XMI>

View File

@ -0,0 +1,331 @@
<?xml version="1.0" encoding="UTF-8"?>
<XMI verified="false" timestamp="2021-01-11T15:50:46" xmlns:UML="http://schema.omg.org/spec/UML/1.4" xmi.version="1.2">
<XMI.header>
<XMI.documentation>
<XMI.exporter>umbrello uml modeller http://umbrello.kde.org</XMI.exporter>
<XMI.exporterVersion>1.6.17</XMI.exporterVersion>
<XMI.exporterEncoding>UnicodeUTF8</XMI.exporterEncoding>
</XMI.documentation>
<XMI.metamodel xmi.name="UML" xmi.version="1.4" href="UML.xml"/>
</XMI.header>
<XMI.content>
<UML:Model xmi.id="m1" isLeaf="false" isAbstract="false" name="UML Model" isSpecification="false" isRoot="false">
<UML:Namespace.ownedElement>
<UML:Stereotype xmi.id="folder" isLeaf="false" isAbstract="false" visibility="public" name="folder" isSpecification="false" namespace="m1" isRoot="false"/>
<UML:Model xmi.id="Logical_View" isLeaf="false" isAbstract="false" visibility="public" name="Logical View" isSpecification="false" namespace="m1" isRoot="false">
<UML:Namespace.ownedElement>
<UML:Package xmi.id="Datatypes" stereotype="folder" isLeaf="false" isAbstract="false" visibility="public" name="Datatypes" isSpecification="false" namespace="Logical_View" isRoot="false">
<UML:Namespace.ownedElement>
<UML:DataType xmi.id="u4xIFQFMKzJrw" isLeaf="false" isAbstract="false" visibility="public" name="char" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uUrqcj6xGhwaC" isLeaf="false" isAbstract="false" visibility="public" name="int" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="u2CL1gZXtSnOS" isLeaf="false" isAbstract="false" visibility="public" name="float" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="u2wysBNkFNdqp" isLeaf="false" isAbstract="false" visibility="public" name="double" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="usYHH6veFLtOr" isLeaf="false" isAbstract="false" visibility="public" name="bool" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uN90WSzxg70L5" isLeaf="false" isAbstract="false" visibility="public" name="string" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uks0OAl3npzAp" isLeaf="false" isAbstract="false" visibility="public" name="unsigned char" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="unwvIxd81D8F6" isLeaf="false" isAbstract="false" visibility="public" name="signed char" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uegsqNCOwThlg" isLeaf="false" isAbstract="false" visibility="public" name="unsigned int" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="u8U3EclXHUBqf" isLeaf="false" isAbstract="false" visibility="public" name="signed int" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uHcFFwtOW2QoG" isLeaf="false" isAbstract="false" visibility="public" name="short int" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="u3gksr7QwMjSv" isLeaf="false" isAbstract="false" visibility="public" name="unsigned short int" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uc2wrhdQQFdKR" isLeaf="false" isAbstract="false" visibility="public" name="signed short int" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uO1NrEETU4UC8" isLeaf="false" isAbstract="false" visibility="public" name="long int" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="umes0MFf2bAXI" isLeaf="false" isAbstract="false" visibility="public" name="signed long int" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uIzLslKdzkNSu" isLeaf="false" isAbstract="false" visibility="public" name="unsigned long int" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uuismMojqbmsx" isLeaf="false" isAbstract="false" visibility="public" name="long double" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uaxm6xi0OF7H9" isLeaf="false" isAbstract="false" visibility="public" name="wchar_t" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uKoxqBVMuFAFv" isLeaf="false" isAbstract="false" visibility="public" name="blob" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="udJEUGSmFsMc7" isLeaf="false" isAbstract="false" visibility="public" name="bigint" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="u0C5GYVgNAN71" isLeaf="false" isAbstract="false" visibility="public" name="date" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="u9FKE3RWhiqcG" isLeaf="false" isAbstract="false" visibility="public" name="datetime" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uhDxBNpwOBqQw" isLeaf="false" isAbstract="false" visibility="public" name="decimal" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uHqbfHWPho1Ur" isLeaf="false" isAbstract="false" visibility="public" name="enum" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uya6iY5Q7DGeZ" isLeaf="false" isAbstract="false" visibility="public" name="longblob" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uaeIOuN6e4FU1" isLeaf="false" isAbstract="false" visibility="public" name="longtext" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="u8zuwCW44JB95" isLeaf="false" isAbstract="false" visibility="public" name="mediumblob" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uGdQJaRR6gTOr" isLeaf="false" isAbstract="false" visibility="public" name="mediumint" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uYevwcNN1qRSX" isLeaf="false" isAbstract="false" visibility="public" name="mediumtext" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uApLJztW3N1vU" isLeaf="false" isAbstract="false" visibility="public" name="set" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uCMJShOyEcx65" isLeaf="false" isAbstract="false" visibility="public" name="smallint" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uMXT4n4yeeGxP" isLeaf="false" isAbstract="false" visibility="public" name="text" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uZPyITrjct7nt" isLeaf="false" isAbstract="false" visibility="public" name="time" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uJlnCmWCjiZyb" isLeaf="false" isAbstract="false" visibility="public" name="timestamp" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uJ6eIdSRnQ1mC" isLeaf="false" isAbstract="false" visibility="public" name="tinyblob" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uFa0n9CbZAGQz" isLeaf="false" isAbstract="false" visibility="public" name="tinyint" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uUmpoisGYNixK" isLeaf="false" isAbstract="false" visibility="public" name="tinytext" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uCYvllFCLICqv" isLeaf="false" isAbstract="false" visibility="public" name="varchar" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uJPiqYCPjwNHv" isLeaf="false" isAbstract="false" visibility="public" name="year" isSpecification="false" namespace="Datatypes" isRoot="false"/>
<UML:DataType xmi.id="uy27kWMqeaG0m" isLeaf="false" isAbstract="false" visibility="public" name="character varying" isSpecification="false" namespace="Datatypes" isRoot="false"/>
</UML:Namespace.ownedElement>
</UML:Package>
</UML:Namespace.ownedElement>
<XMI.extension xmi.extender="umbrello">
<diagrams resolution="96">
<diagram documentation="" showstereotype="1" textcolor="#000000" showattribassocs="1" name="class diagram" snapy="25" zoom="100" showops="1" showopsig="1" fillcolor="#ffff00" showpackage="1" canvaswidth="0" isopen="1" backgroundcolor="#ffffff" showpubliconly="0" snapgrid="0" snapx="25" xmi.id="ucgtgQRSMYlOp" showatts="1" type="1" griddotcolor="#d3d3d3" showattsig="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" showgrid="0" showscope="1" linecolor="#ff0000" snapcsgrid="0" linewidth="0" usefillcolor="1" localid="-1" canvasheight="0">
<widgets/>
<messages/>
<associations/>
</diagram>
</diagrams>
</XMI.extension>
</UML:Model>
<UML:Model xmi.id="Use_Case_View" isLeaf="false" isAbstract="false" visibility="public" name="Use Case View" isSpecification="false" namespace="m1" isRoot="false">
<UML:Namespace.ownedElement/>
</UML:Model>
<UML:Model xmi.id="Component_View" isLeaf="false" isAbstract="false" visibility="public" name="Component View" isSpecification="false" namespace="m1" isRoot="false">
<UML:Namespace.ownedElement/>
</UML:Model>
<UML:Model xmi.id="Deployment_View" isLeaf="false" isAbstract="false" visibility="public" name="Deployment View" isSpecification="false" namespace="m1" isRoot="false">
<UML:Namespace.ownedElement/>
</UML:Model>
<UML:Model xmi.id="Entity_Relationship_Model" isLeaf="false" isAbstract="false" visibility="public" name="Entity Relationship Model" isSpecification="false" namespace="m1" isRoot="false">
<UML:Namespace.ownedElement>
<UML:Entity xmi.id="unciQy8XxFf2T" isLeaf="false" isAbstract="false" visibility="public" name="adjudicated" isSpecification="false" namespace="Entity_Relationship_Model" isRoot="false">
<UML:EntityAttribute xmi.id="uMy5ahFmN0KRD" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="claim_id" isSpecification="false" namespace="unciQy8XxFf2T" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="ubJdB6RGlsKyI" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="adjudicated_procedure_cd" isSpecification="false" namespace="unciQy8XxFf2T" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uW0mYtdR4tpSX" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="adjudicated_procedure_cd_qual" isSpecification="false" namespace="unciQy8XxFf2T" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="ujq5GJmFPNCgS" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="adjudicated_proc_modifier_1" isSpecification="false" namespace="unciQy8XxFf2T" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uXwwLwuES808h" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="adjudicated_proc_modifier_2" isSpecification="false" namespace="unciQy8XxFf2T" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uvpv92xuc6vb5" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="adjudicated_proc_modifier_3" isSpecification="false" namespace="unciQy8XxFf2T" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="ugpN8ZjPYZz0b" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="adjudicated_proc_modifier_4" isSpecification="false" namespace="unciQy8XxFf2T" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="u0cbN6lqPZFq5" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="_index" isSpecification="false" namespace="unciQy8XxFf2T" values="125" isRoot="false"/>
</UML:Entity>
<UML:Entity xmi.id="u7JoY1YgBbZBw" isLeaf="false" isAbstract="false" visibility="public" name="adjustments" isSpecification="false" namespace="Entity_Relationship_Model" isRoot="false">
<UML:EntityAttribute xmi.id="uJWMJDJW7OPHZ" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="claim_id" isSpecification="false" namespace="u7JoY1YgBbZBw" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="ut2LR9qmsrOKs" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="amount" isSpecification="false" namespace="u7JoY1YgBbZBw" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uPRzkRJCCJabo" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="reason" isSpecification="false" namespace="u7JoY1YgBbZBw" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uCGGZqIN2sQH3" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="quantity" isSpecification="false" namespace="u7JoY1YgBbZBw" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="utB3YD4uBHDFe" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="group_code" isSpecification="false" namespace="u7JoY1YgBbZBw" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uJB8h1NGbex2g" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="reason_code" isSpecification="false" namespace="u7JoY1YgBbZBw" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uSWWvOUaew5HP" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="adustment_amount" isSpecification="false" namespace="u7JoY1YgBbZBw" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uF4C162xw4VxT" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="adjustment_quantity" isSpecification="false" namespace="u7JoY1YgBbZBw" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uized1QFwg0ct" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="_index" isSpecification="false" namespace="u7JoY1YgBbZBw" values="125" isRoot="false"/>
</UML:Entity>
<UML:Entity xmi.id="uYFy5I3jZovwB" isLeaf="false" isAbstract="false" visibility="public" name="dates" isSpecification="false" namespace="Entity_Relationship_Model" isRoot="false">
<UML:EntityAttribute xmi.id="u19O44eIBLpSx" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="claim_id" isSpecification="false" namespace="uYFy5I3jZovwB" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="u24TxypfX1ehF" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="type" isSpecification="false" namespace="uYFy5I3jZovwB" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="u1rGJT5BzOnTc" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="date" isSpecification="false" namespace="uYFy5I3jZovwB" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uh1XMXOFqqkLH" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="claim_received_by_payer_date" isSpecification="false" namespace="uYFy5I3jZovwB" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="udhZrX8aJ7mx2" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="_index" isSpecification="false" namespace="uYFy5I3jZovwB" values="125" isRoot="false"/>
</UML:Entity>
<UML:Entity xmi.id="uQLb3AjtJtg1u" isLeaf="false" isAbstract="false" visibility="public" name="procedures" isSpecification="false" namespace="Entity_Relationship_Model" isRoot="false">
<UML:EntityAttribute xmi.id="uAjDOjucMMjVA" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="claim_id" isSpecification="false" namespace="uQLb3AjtJtg1u" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uvwYZ2ZXVtktZ" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="code" isSpecification="false" namespace="uQLb3AjtJtg1u" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uK1hOh0gYH7UR" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="amount" isSpecification="false" namespace="uQLb3AjtJtg1u" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uzXoWRaQEBR4N" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="line_charge_amount" isSpecification="false" namespace="uQLb3AjtJtg1u" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uTu2N31LFQjZs" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="submitted_units_of_service" isSpecification="false" namespace="uQLb3AjtJtg1u" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uX3uZJhBt3XbF" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="revenue_code" isSpecification="false" namespace="uQLb3AjtJtg1u" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="u1iY5DjVfwxct" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="paid_units_of_service" isSpecification="false" namespace="uQLb3AjtJtg1u" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="udHyId5EQgnxd" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="line_paid_amount" isSpecification="false" namespace="uQLb3AjtJtg1u" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="ucBf8PfYusdLF" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="_index" isSpecification="false" namespace="uQLb3AjtJtg1u" values="125" isRoot="false"/>
</UML:Entity>
<UML:Entity xmi.id="uxCXzVM24yYaX" isLeaf="false" isAbstract="false" visibility="public" name="provider" isSpecification="false" namespace="Entity_Relationship_Model" isRoot="false">
<UML:EntityAttribute xmi.id="ucbfGJzClrgx7" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="claim_id" isSpecification="false" namespace="uxCXzVM24yYaX" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="ui5GIXpde552t" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="provider_id" isSpecification="false" namespace="uxCXzVM24yYaX" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uqpcLcCfQxPc1" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="adjustment_fiscal_year" isSpecification="false" namespace="uxCXzVM24yYaX" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="u8EKwCD4KJD35" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="adjustment_amount" isSpecification="false" namespace="uxCXzVM24yYaX" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="ugSzBbS45Appb" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="_index" isSpecification="false" namespace="uxCXzVM24yYaX" values="125" isRoot="false"/>
</UML:Entity>
<UML:Entity xmi.id="uFhe3BvJ5GFMv" isLeaf="false" isAbstract="false" visibility="public" name="remits" isSpecification="false" namespace="Entity_Relationship_Model" isRoot="false">
<UML:EntityAttribute xmi.id="uaPrhdtHj174f" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="claim_id" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="umBq8tNVoHLwQ" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="charge_amount" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="u2TjnY4FpRX7E" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="payment_amount" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uO0RFshYIUxyV" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="patient_amount" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="u26a7mGlibP31" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="patient_status" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uqT7KYiudzE2a" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="status" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="utDLqzoqgcm98" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="total_paid_amt" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="u4760sev0qJdC" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="total_claim_charge_amount" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uYOWi0TRwwQ9C" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="patient_responsibility_amount" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uTmKxBb1U6HHd" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="drug_code" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="u8b87l43udLdm" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="type_of_bill" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="ussv42OpwEC3o" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="claim_control_number" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uutC8Ww5MIEDw" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="type_of_coverage" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uVwZLtkVRxhLS" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="place_of_service" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uMxluIdcl530X" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="claim_status" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="u35C8cp4M74EZ" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="transaction_type" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uGKSxco6bkhJK" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="transaction_amount" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uFR0HPZWCHTOd" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="transaction_method" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uRKSgcFBa5IZo" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="date_paid" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uTI9AfIOT6Vgi" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="billing_pr_adr_line_1" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uh7Mo4vNDxjEP" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="billing_pr_adr_line_2" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uIOoyY9AcSXqj" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="billing_pr_adr_zip" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uM8YUylmQOOZz" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="billing_pr_adr_state" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="ueFTa93wS5vpr" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="billing_pr_adr_city" isSpecification="false" namespace="uFhe3BvJ5GFMv" values="125" isRoot="false"/>
</UML:Entity>
<UML:Entity xmi.id="uDyfldNoIv0VN" isLeaf="false" isAbstract="false" visibility="public" name="submitted_procedures" isSpecification="false" namespace="Entity_Relationship_Model" isRoot="false">
<UML:EntityAttribute xmi.id="uHlzHdGAzTLje" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="claim_id" isSpecification="false" namespace="uDyfldNoIv0VN" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uTdAUNse734xO" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="submitted_procedure_cd" isSpecification="false" namespace="uDyfldNoIv0VN" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="usy1XBeLxeUGA" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="submitted_procedure_cd_qual" isSpecification="false" namespace="uDyfldNoIv0VN" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uXzmRTjxt5urK" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="submitted_proc_modifier_1" isSpecification="false" namespace="uDyfldNoIv0VN" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uZaNNwlpF8G8D" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="submitted_proc_modifier_2" isSpecification="false" namespace="uDyfldNoIv0VN" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uTVrpMWQGZv9k" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="submitted_proc_modifier_3" isSpecification="false" namespace="uDyfldNoIv0VN" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uDVH1N8QTr4Hh" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="submitted_proc_modifier_4" isSpecification="false" namespace="uDyfldNoIv0VN" values="125" isRoot="false"/>
<UML:EntityAttribute xmi.id="uiSnbXbl5xZgj" allow_null="1" dbindex_type="1100" isLeaf="false" isAbstract="false" visibility="public" initialValue="" attributes="" type="uy27kWMqeaG0m" auto_increment="0" name="_index" isSpecification="false" namespace="uDyfldNoIv0VN" values="125" isRoot="false"/>
</UML:Entity>
</UML:Namespace.ownedElement>
<XMI.extension xmi.extender="umbrello">
<diagrams resolution="96">
<diagram documentation="" showstereotype="1" textcolor="#000000" showattribassocs="1" name="remits" snapy="25" zoom="100" showops="1" showopsig="1" fillcolor="#ffff00" showpackage="1" canvaswidth="1599" isopen="1" backgroundcolor="#ffffff" showpubliconly="0" snapgrid="1" snapx="25" xmi.id="uKioLvROZP9sj" showatts="1" type="9" griddotcolor="#d3d3d3" showattsig="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" showgrid="0" showscope="1" linecolor="#000000" snapcsgrid="0" linewidth="0" usefillcolor="0" localid="-1" canvasheight="556">
<widgets>
<entitywidget width="374" showstereotype="1" textcolor="#000000" showattsigs="1" autoresize="1" usesdiagramusefillcolor="0" height="131" fillcolor="#ffff00" x="-400" xmi.id="unciQy8XxFf2T" isinstance="0" y="-325" font="Sans Serif,9,-1,5,50,0,0,0,0,0" usesdiagramfillcolor="0" linecolor="#000000" linewidth="0" localid="u9BawkrPSkiAR" usefillcolor="0"/>
<entitywidget width="373" showstereotype="1" textcolor="#000000" showattsigs="1" autoresize="0" usesdiagramusefillcolor="0" height="145" fillcolor="#ffff00" x="-400" xmi.id="u7JoY1YgBbZBw" isinstance="0" y="-150" font="Sans Serif,9,-1,5,50,0,0,0,0,0" usesdiagramfillcolor="0" linecolor="#000000" linewidth="0" localid="u4iVjIspsosQL" usefillcolor="0"/>
<entitywidget width="374" showstereotype="1" textcolor="#000000" showattsigs="1" autoresize="0" usesdiagramusefillcolor="0" height="90" fillcolor="#ffff00" x="-400" xmi.id="uYFy5I3jZovwB" isinstance="0" y="25" font="Sans Serif,9,-1,5,50,0,0,0,0,0" usesdiagramfillcolor="0" linecolor="#000000" linewidth="0" localid="u2C9V7ZineWlR" usefillcolor="0"/>
<entitywidget width="362" showstereotype="1" textcolor="#000000" showattsigs="1" autoresize="0" usesdiagramusefillcolor="0" height="147" fillcolor="#ffff00" x="-1250" xmi.id="uQLb3AjtJtg1u" isinstance="0" y="-325" font="Sans Serif,9,-1,5,50,0,0,0,0,0" usesdiagramfillcolor="0" linecolor="#000000" linewidth="0" localid="urgFkiZg2gtuo" usefillcolor="0"/>
<entitywidget width="364" showstereotype="1" textcolor="#000000" showattsigs="0" autoresize="0" usesdiagramusefillcolor="0" height="124" fillcolor="#ffff00" x="-1250" xmi.id="uxCXzVM24yYaX" isinstance="0" y="-150" font="Sans Serif,9,-1,5,50,0,0,0,0,0" usesdiagramfillcolor="0" linecolor="#000000" linewidth="0" localid="uCObA80MWNOaQ" usefillcolor="0"/>
<entitywidget width="373" showstereotype="1" textcolor="#000000" showattsigs="1" autoresize="0" usesdiagramusefillcolor="0" height="452" fillcolor="#ffff00" x="-825" xmi.id="uFhe3BvJ5GFMv" isinstance="0" y="-325" font="Sans Serif,9,-1,5,50,0,0,0,0,0" usesdiagramfillcolor="0" linecolor="#000000" linewidth="0" localid="ujz1Vg5ZL42FJ" usefillcolor="0"/>
<entitywidget width="362" showstereotype="1" textcolor="#000000" showattsigs="0" autoresize="0" usesdiagramusefillcolor="0" height="131" fillcolor="#ffff00" x="-1250" xmi.id="uDyfldNoIv0VN" isinstance="0" y="0" font="Sans Serif,9,-1,5,50,0,0,0,0,0" usesdiagramfillcolor="0" linecolor="#000000" linewidth="0" localid="umfGrEfhw5trO" usefillcolor="0"/>
<floatingtext width="257" showstereotype="1" textcolor="#000000" pretext="" autoresize="1" usesdiagramusefillcolor="0" height="35" fillcolor="#ffff00" x="-1625" xmi.id="uojLF0iPnR6e2" isinstance="0" y="-425" text="835 REMITTANCES" font="Sans Serif,20,-1,5,50,0,0,0,0,0" usesdiagramfillcolor="0" linecolor="#000000" role="700" linewidth="0" localid="uSSnE3AdKsGoB" usefillcolor="0" posttext=""/>
</widgets>
<messages/>
<associations/>
</diagram>
</diagrams>
</XMI.extension>
</UML:Model>
</UML:Namespace.ownedElement>
</UML:Model>
</XMI.content>
<XMI.extensions xmi.extender="umbrello">
<docsettings viewid="uKioLvROZP9sj" documentation="" uniqueid="ueCKqCZwQu4Lk"/>
<listview>
<listitem type="800" id="Views" open="1">
<listitem type="821" id="Component_View" open="1"/>
<listitem type="827" id="Deployment_View" open="1"/>
<listitem type="836" id="Entity_Relationship_Model" open="1">
<listitem type="832" id="unciQy8XxFf2T" open="0">
<listitem type="833" id="u0cbN6lqPZFq5" open="0"/>
<listitem type="833" id="ujq5GJmFPNCgS" open="0"/>
<listitem type="833" id="uXwwLwuES808h" open="0"/>
<listitem type="833" id="uvpv92xuc6vb5" open="0"/>
<listitem type="833" id="ugpN8ZjPYZz0b" open="0"/>
<listitem type="833" id="ubJdB6RGlsKyI" open="0"/>
<listitem type="833" id="uW0mYtdR4tpSX" open="0"/>
<listitem type="833" id="uMy5ahFmN0KRD" open="0"/>
</listitem>
<listitem type="832" id="u7JoY1YgBbZBw" open="0">
<listitem type="833" id="uized1QFwg0ct" open="0"/>
<listitem type="833" id="uF4C162xw4VxT" open="0"/>
<listitem type="833" id="uSWWvOUaew5HP" open="0"/>
<listitem type="833" id="ut2LR9qmsrOKs" open="0"/>
<listitem type="833" id="uJWMJDJW7OPHZ" open="0"/>
<listitem type="833" id="utB3YD4uBHDFe" open="0"/>
<listitem type="833" id="uCGGZqIN2sQH3" open="0"/>
<listitem type="833" id="uPRzkRJCCJabo" open="0"/>
<listitem type="833" id="uJB8h1NGbex2g" open="0"/>
</listitem>
<listitem type="832" id="uYFy5I3jZovwB" open="0">
<listitem type="833" id="udhZrX8aJ7mx2" open="0"/>
<listitem type="833" id="u19O44eIBLpSx" open="0"/>
<listitem type="833" id="uh1XMXOFqqkLH" open="0"/>
<listitem type="833" id="u1rGJT5BzOnTc" open="0"/>
<listitem type="833" id="u24TxypfX1ehF" open="0"/>
</listitem>
<listitem type="832" id="uQLb3AjtJtg1u" open="0">
<listitem type="833" id="ucBf8PfYusdLF" open="0"/>
<listitem type="833" id="uK1hOh0gYH7UR" open="0"/>
<listitem type="833" id="uAjDOjucMMjVA" open="0"/>
<listitem type="833" id="uvwYZ2ZXVtktZ" open="0"/>
<listitem type="833" id="uzXoWRaQEBR4N" open="0"/>
<listitem type="833" id="udHyId5EQgnxd" open="0"/>
<listitem type="833" id="u1iY5DjVfwxct" open="0"/>
<listitem type="833" id="uX3uZJhBt3XbF" open="0"/>
<listitem type="833" id="uTu2N31LFQjZs" open="0"/>
</listitem>
<listitem type="832" id="uxCXzVM24yYaX" open="0">
<listitem type="833" id="ugSzBbS45Appb" open="0"/>
<listitem type="833" id="u8EKwCD4KJD35" open="0"/>
<listitem type="833" id="uqpcLcCfQxPc1" open="0"/>
<listitem type="833" id="ucbfGJzClrgx7" open="0"/>
<listitem type="833" id="ui5GIXpde552t" open="0"/>
</listitem>
<listitem type="832" id="uFhe3BvJ5GFMv" open="0">
<listitem type="833" id="ueFTa93wS5vpr" open="0"/>
<listitem type="833" id="uTI9AfIOT6Vgi" open="0"/>
<listitem type="833" id="uh7Mo4vNDxjEP" open="0"/>
<listitem type="833" id="uM8YUylmQOOZz" open="0"/>
<listitem type="833" id="uIOoyY9AcSXqj" open="0"/>
<listitem type="833" id="umBq8tNVoHLwQ" open="0"/>
<listitem type="833" id="ussv42OpwEC3o" open="0"/>
<listitem type="833" id="uaPrhdtHj174f" open="0"/>
<listitem type="833" id="uMxluIdcl530X" open="0"/>
<listitem type="833" id="uRKSgcFBa5IZo" open="0"/>
<listitem type="833" id="uTmKxBb1U6HHd" open="0"/>
<listitem type="833" id="uO0RFshYIUxyV" open="0"/>
<listitem type="833" id="uYOWi0TRwwQ9C" open="0"/>
<listitem type="833" id="u26a7mGlibP31" open="0"/>
<listitem type="833" id="u2TjnY4FpRX7E" open="0"/>
<listitem type="833" id="uVwZLtkVRxhLS" open="0"/>
<listitem type="833" id="uqT7KYiudzE2a" open="0"/>
<listitem type="833" id="u4760sev0qJdC" open="0"/>
<listitem type="833" id="utDLqzoqgcm98" open="0"/>
<listitem type="833" id="uGKSxco6bkhJK" open="0"/>
<listitem type="833" id="uFR0HPZWCHTOd" open="0"/>
<listitem type="833" id="u35C8cp4M74EZ" open="0"/>
<listitem type="833" id="u8b87l43udLdm" open="0"/>
<listitem type="833" id="uutC8Ww5MIEDw" open="0"/>
</listitem>
<listitem label="remits" type="834" id="uKioLvROZP9sj" open="0"/>
<listitem type="832" id="uDyfldNoIv0VN" open="0">
<listitem type="833" id="uiSnbXbl5xZgj" open="0"/>
<listitem type="833" id="uHlzHdGAzTLje" open="0"/>
<listitem type="833" id="uXzmRTjxt5urK" open="0"/>
<listitem type="833" id="uZaNNwlpF8G8D" open="0"/>
<listitem type="833" id="uTVrpMWQGZv9k" open="0"/>
<listitem type="833" id="uDVH1N8QTr4Hh" open="0"/>
<listitem type="833" id="uTdAUNse734xO" open="0"/>
<listitem type="833" id="usy1XBeLxeUGA" open="0"/>
</listitem>
</listitem>
<listitem type="801" id="Logical_View" open="1">
<listitem label="class diagram" type="807" id="ucgtgQRSMYlOp" open="0"/>
<listitem type="830" id="Datatypes" open="0">
<listitem type="829" id="udJEUGSmFsMc7" open="1"/>
<listitem type="829" id="uKoxqBVMuFAFv" open="1"/>
<listitem type="829" id="usYHH6veFLtOr" open="0"/>
<listitem type="829" id="u4xIFQFMKzJrw" open="0"/>
<listitem type="829" id="uy27kWMqeaG0m" open="0"/>
<listitem type="829" id="u0C5GYVgNAN71" open="1"/>
<listitem type="829" id="u9FKE3RWhiqcG" open="1"/>
<listitem type="829" id="uhDxBNpwOBqQw" open="1"/>
<listitem type="829" id="u2wysBNkFNdqp" open="0"/>
<listitem type="829" id="uHqbfHWPho1Ur" open="1"/>
<listitem type="829" id="u2CL1gZXtSnOS" open="0"/>
<listitem type="829" id="uUrqcj6xGhwaC" open="0"/>
<listitem type="829" id="uuismMojqbmsx" open="0"/>
<listitem type="829" id="uO1NrEETU4UC8" open="0"/>
<listitem type="829" id="uya6iY5Q7DGeZ" open="1"/>
<listitem type="829" id="uaeIOuN6e4FU1" open="1"/>
<listitem type="829" id="u8zuwCW44JB95" open="1"/>
<listitem type="829" id="uGdQJaRR6gTOr" open="1"/>
<listitem type="829" id="uYevwcNN1qRSX" open="1"/>
<listitem type="829" id="uApLJztW3N1vU" open="1"/>
<listitem type="829" id="uHcFFwtOW2QoG" open="0"/>
<listitem type="829" id="unwvIxd81D8F6" open="0"/>
<listitem type="829" id="u8U3EclXHUBqf" open="0"/>
<listitem type="829" id="umes0MFf2bAXI" open="0"/>
<listitem type="829" id="uc2wrhdQQFdKR" open="0"/>
<listitem type="829" id="uCMJShOyEcx65" open="1"/>
<listitem type="829" id="uN90WSzxg70L5" open="0"/>
<listitem type="829" id="uMXT4n4yeeGxP" open="1"/>
<listitem type="829" id="uZPyITrjct7nt" open="1"/>
<listitem type="829" id="uJlnCmWCjiZyb" open="1"/>
<listitem type="829" id="uJ6eIdSRnQ1mC" open="1"/>
<listitem type="829" id="uFa0n9CbZAGQz" open="1"/>
<listitem type="829" id="uUmpoisGYNixK" open="1"/>
<listitem type="829" id="uks0OAl3npzAp" open="0"/>
<listitem type="829" id="uegsqNCOwThlg" open="0"/>
<listitem type="829" id="uIzLslKdzkNSu" open="0"/>
<listitem type="829" id="u3gksr7QwMjSv" open="0"/>
<listitem type="829" id="uCYvllFCLICqv" open="1"/>
<listitem type="829" id="uaxm6xi0OF7H9" open="0"/>
<listitem type="829" id="uJPiqYCPjwNHv" open="1"/>
</listitem>
</listitem>
<listitem type="802" id="Use_Case_View" open="1"/>
</listitem>
</listview>
<codegeneration>
<codegenerator language="SQL"/>
</codegeneration>
</XMI.extensions>
</XMI>

View File

@ -32,9 +32,10 @@ Usage :
from healthcareio.params import SYS_ARGS
from transport import factory
import requests
from healthcareio import analytics
from healthcareio import server
from healthcareio.parser import get_content
import os
import json
@ -43,6 +44,10 @@ import numpy as np
from multiprocessing import Process
import time
from healthcareio import x12
from healthcareio.export import export
import smart
from healthcareio.server import proxy
import pandas as pd
PATH = os.sep.join([os.environ['HOME'],'.healthcareio'])
OUTPUT_FOLDER = os.sep.join([os.environ['HOME'],'healthcare-io'])
@ -53,10 +58,28 @@ if not os.path.exists(PATH) :
import platform
import sqlite3 as lite
# PATH = os.sep.join([os.environ['HOME'],'.edi-parser'])
def register (**args) :
HELP_MESSAGE = """
cli:
healthcare-io.py --<[signup|init]> <email> --store <sqlite|mongo> [--batch <value>]
healthcare-io.py --parse --folder <path> [--batch <value>] [--resume]
healthcare-io.py --check-update
healthcare-io.py --export <835|837> --config <config-path>
action :
--signup|init signup user and get configuration file
--parse starts parsing
--check checks for updates
--export export data of a 835 or 837 into another database
parameters :
--<[signup|init]> signup or get a configuration file from a parsing server
--folder location of the files (the program will recursively traverse it)
--store data store mongo or sqlite or mongodb
--resume will attempt to resume if there was an interruption
"""
def signup (**args) :
"""
:email user's email address
:url url of the provider to register
:url url of the provider to signup
"""
email = args['email']
@ -121,77 +144,77 @@ def init():
#
# Global variables that load the configuration files
def parse(**args):
"""
This function will parse the content of a claim or remittance (x12 format) give the following parameters
:filename absolute path of the file to be parsed
:type claims|remits in x12 format
"""
global INFO
if not INFO :
INFO = init()
if args['type'] == 'claims' :
CONFIG = INFO['parser']['837']
elif args['type'] == 'remits' :
CONFIG = INFO['parser']['835']
else:
CONFIG = None
if CONFIG :
# CONFIG = CONFIG[-1] if 'version' not in args and (args['version'] < len(CONFIG)) else CONFIG[0]
CONFIG = CONFIG[int(args['version'])-1] if 'version' in SYS_ARGS and int(SYS_ARGS['version']) < len(CONFIG) else CONFIG[-1]
SECTION = CONFIG['SECTION']
os.environ['HEALTHCAREIO_SALT'] = INFO['owner']
# def parse(**args):
# """
# This function will parse the content of a claim or remittance (x12 format) give the following parameters
# :filename absolute path of the file to be parsed
# :type claims|remits in x12 format
# """
# global INFO
# if not INFO :
# INFO = init()
# if args['type'] == 'claims' :
# CONFIG = INFO['parser']['837']
# elif args['type'] == 'remits' :
# CONFIG = INFO['parser']['835']
# else:
# CONFIG = None
# if CONFIG :
# # CONFIG = CONFIG[-1] if 'version' not in args and (args['version'] < len(CONFIG)) else CONFIG[0]
# CONFIG = CONFIG[int(args['version'])-1] if 'version' in SYS_ARGS and int(SYS_ARGS['version']) < len(CONFIG) else CONFIG[-1]
# SECTION = CONFIG['SECTION']
# os.environ['HEALTHCAREIO_SALT'] = INFO['owner']
return get_content(args['filename'],CONFIG,SECTION)
def resume (files,id,config):
_args = config['store'].copy()
if 'mongo' in config['store']['type'] :
_args['type'] = 'mongo.MongoReader'
reader = factory.instance(**_args)
_files = []
if 'resume' in config['analytics'] :
_args = config['analytics']['resume'][id]
_files = reader.read(**_args)
_files = [item['name'] for item in _files if item['name'] != None]
return list(set(files) - set(_files))
# return get_content(args['filename'],CONFIG,SECTION)
# def resume (files,id,config):
# _args = config['store'].copy()
# if 'mongo' in config['store']['type'] :
# _args['type'] = 'mongo.MongoReader'
# reader = factory.instance(**_args)
# _files = []
# if 'resume' in config['analytics'] :
# _args = config['analytics']['resume'][id]
# _files = reader.read(**_args)
# _files = [item['name'] for item in _files if item['name'] != None]
# return list(set(files) - set(_files))
return files
pass
def apply(files,store_info,logger_info=None):
"""
:files list of files to be processed in this given thread/process
:store_info information about data-store, for now disk isn't thread safe
:logger_info information about where to store the logs
"""
# return files
# pass
# def apply(files,store_info,logger_info=None):
# """
# :files list of files to be processed in this given thread/process
# :store_info information about data-store, for now disk isn't thread safe
# :logger_info information about where to store the logs
# """
if not logger_info :
logger = factory.instance(type='disk.DiskWriter',args={'path':os.sep.join([info['out-folder'],SYS_ARGS['parse']+'.log'])})
else:
logger = factory.instance(**logger_info)
# if not logger_info :
# logger = factory.instance(type='disk.DiskWriter',args={'path':os.sep.join([info['out-folder'],SYS_ARGS['parse']+'.log'])})
# else:
# logger = factory.instance(**logger_info)
writer = factory.instance(**store_info)
for filename in files :
# writer = factory.instance(**store_info)
# for filename in files :
if filename.strip() == '':
continue
# content,logs = get_content(filename,CONFIG,CONFIG['SECTION'])
#
try:
content,logs = parse(filename = filename,type=SYS_ARGS['parse'])
# if filename.strip() == '':
# continue
# # content,logs = get_content(filename,CONFIG,CONFIG['SECTION'])
# #
# try:
# content,logs = parse(filename = filename,type=SYS_ARGS['parse'])
if content :
writer.write(content)
if logs :
[logger.write(dict(_row,**{"parse":SYS_ARGS['parse']})) for _row in logs]
else:
logger.write({"parse":SYS_ARGS['parse'],"name":filename,"completed":True,"rows":len(content)})
except Exception as e:
# if content :
# writer.write(content)
# if logs :
# [logger.write(dict(_row,**{"parse":SYS_ARGS['parse']})) for _row in logs]
# else:
# logger.write({"parse":SYS_ARGS['parse'],"name":filename,"completed":True,"rows":len(content)})
# except Exception as e:
logger.write({"parse":SYS_ARGS['parse'],"filename":filename,"completed":False,"rows":-1,"msg":e.args[0]})
# print ([filename,len(content)])
#
# @TODO: forward this data to the writer and log engine
# logger.write({"parse":SYS_ARGS['parse'],"filename":filename,"completed":False,"rows":-1,"msg":e.args[0]})
# # print ([filename,len(content)])
# #
# # @TODO: forward this data to the writer and log engine
#
def upgrade(**args):
"""
@ -200,13 +223,28 @@ def upgrade(**args):
"""
url = args['url'] if 'url' in args else URL+"/upgrade"
headers = {"key":args['key'],"email":args["email"],"url":url}
def check(**_args):
"""
This function will check if there is an update available (versions are in the configuration file)
:param url
"""
url = _args['url'][:-1] if _args['url'].endswith('/') else _args['url']
url = url + "/version"
if 'version' not in _args :
version = {"_id":"version","current":0.0}
else:
version = _args['version']
http = requests.session()
r = http.get(url)
return r.json()
if __name__ == '__main__' :
info = init()
if 'out-folder' in SYS_ARGS :
OUTPUT_FOLDER = SYS_ARGS['out-folder']
SYS_ARGS['url'] = SYS_ARGS['url'] if 'url' in SYS_ARGS else URL
if set(list(SYS_ARGS.keys())) & set(['signup','init']):
#
# This command will essentially get a new copy of the configurations
@ -214,10 +252,10 @@ if __name__ == '__main__' :
#
email = SYS_ARGS['signup'].strip() if 'signup' in SYS_ARGS else SYS_ARGS['init']
url = SYS_ARGS['url'] if 'url' in SYS_ARGS else 'https://healthcareio.the-phi.com'
url = SYS_ARGS['url'] if 'url' in SYS_ARGS else URL
store = SYS_ARGS['store'] if 'store' in SYS_ARGS else 'sqlite'
db='healthcareio' if 'db' not in SYS_ARGS else SYS_ARGS['db']
register(email=email,url=url,store=store,db=db)
signup(email=email,url=url,store=store,db=db)
# else:
# m = """
# usage:
@ -241,51 +279,31 @@ if __name__ == '__main__' :
if 'file' in SYS_ARGS :
files = [SYS_ARGS['file']] if not os.path.isdir(SYS_ARGS['file']) else []
if 'folder' in SYS_ARGS and os.path.exists(SYS_ARGS['folder']):
names = os.listdir(SYS_ARGS['folder'])
files += [os.sep.join([SYS_ARGS['folder'],name]) for name in names if not os.path.isdir(os.sep.join([SYS_ARGS['folder'],name]))]
for root,_dir,f in os.walk(SYS_ARGS['folder']) :
if f :
files += [os.sep.join([root,name]) for name in f]
# names = os.listdir(SYS_ARGS['folder'])
# files += [os.sep.join([SYS_ARGS['folder'],name]) for name in names if not os.path.isdir(os.sep.join([SYS_ARGS['folder'],name]))]
else:
#
# raise an erro
# raise an error
pass
#
# if the user has specified to resume, we should look into the logs and pull the files processed and those that haven't
#
if 'resume' in SYS_ARGS :
files = resume(files,SYS_ARGS['parse'],info)
print (["Found ",len(files)," files unprocessed"])
store_config = json.loads( (open(os.sep.join([PATH,'config.json']))).read() )
files = proxy.get.resume(files,store_config )
# print (["Found ",len(files)," files unprocessed"])
#
# @TODO: Log this here so we know what is being processed or not
SCOPE = None
if files : #and ('claims' in SYS_ARGS['parse'] or 'remits' in SYS_ARGS['parse']):
# logger = factory.instance(type='disk.DiskWriter',args={'path':os.sep.join([info['out-folder'],SYS_ARGS['parse']+'.log'])})
# if info['store']['type'] == 'disk.DiskWriter' :
# info['store']['args']['path'] += (os.sep + 'healthcare-io.json')
# elif info['store']['type'] == 'disk.SQLiteWriter' :
# # info['store']['args']['path'] += (os.sep + 'healthcare-io.db3')
# pass
# if info['store']['type'] == 'disk.SQLiteWriter' :
# info['store']['args']['table'] = SYS_ARGS['parse'].strip().lower()
# _info = json.loads(json.dumps(info['store']))
# _info['args']['table']='logs'
# else:
# #
# # if we are working with no-sql we will put the logs in it (performance )?
# info['store']['args']['doc'] = SYS_ARGS['parse'].strip().lower()
# _info = json.loads(json.dumps(info['store']))
# _info['args']['doc'] = 'logs'
# logger = factory.instance(**_info)
# writer = factory.instance(**info['store'])
#
# we need to have batches ready for this in order to run some of these queries in parallel
# @TODO: Make sure it is with a persistence storage (not disk .. not thread/process safe yet)
# - Make sure we can leverage this on n-cores later on, for now the assumption is a single core
#
BATCH_COUNT = 1 if 'batch' not in SYS_ARGS else int (SYS_ARGS['batch'])
files = np.array_split(files,BATCH_COUNT)
@ -304,27 +322,7 @@ if __name__ == '__main__' :
while len(procs) > 0 :
procs = [proc for proc in procs if proc.is_alive()]
time.sleep(2)
# for filename in files :
# if filename.strip() == '':
# continue
# # content,logs = get_content(filename,CONFIG,CONFIG['SECTION'])
# #
# try:
# content,logs = parse(filename = filename,type=SYS_ARGS['parse'])
# if content :
# writer.write(content)
# if logs :
# [logger.write(dict(_row,**{"parse":SYS_ARGS['parse']})) for _row in logs]
# else:
# logger.write({"parse":SYS_ARGS['parse'],"name":filename,"completed":True,"rows":len(content)})
# except Exception as e:
# logger.write({"parse":SYS_ARGS['parse'],"filename":filename,"completed":False,"rows":-1,"msg":e.args[0]})
# # print ([filename,len(content)])
# #
# # @TODO: forward this data to the writer and log engine
# #
pass
@ -337,103 +335,71 @@ if __name__ == '__main__' :
# PATH= SYS_ARGS['config'] if 'config' in SYS_ARGS else os.sep.join([os.environ['HOME'],'.healthcareio','config.json'])
e = analytics.engine(os.sep.join([PATH,'config.json'])) #--@TODO: make the configuration file globally accessible
e.apply(type='claims',serialize=True)
SYS_ARGS['engine'] = e
if os.path.exists(os.sep.join([PATH,'config.json'])) :
e = analytics.engine(os.sep.join([PATH,'config.json'])) #--@TODO: make the configuration file globally accessible
e.apply(type='claims',serialize=True)
SYS_ARGS['engine'] = e
SYS_ARGS['config'] = json.loads(open(os.sep.join([PATH,'config.json'])).read())
else:
SYS_ARGS['config'] = {"owner":None,"store":None}
if 'args' not in SYS_ARGS['config'] :
SYS_ARGS['config']["args"] = {"batch":1,"resume":True,"folder":"/data"}
me = pd.DataFrame(smart.top.read(name='healthcare-io.py')).args.unique().tolist()
SYS_ARGS['me'] = me[0] #-- This key will identify the current process
pointer = lambda : server.app.run(host='0.0.0.0',port=PORT,debug=DEBUG,threaded=False)
pthread = Process(target=pointer,args=())
pthread.start()
elif 'check-update' in SYS_ARGS :
_args = {"url":SYS_ARGS['url']}
try:
if os.path.exists(os.sep.join([PATH,'config.json'])) :
SYS_ARGS['config'] = json.loads((open(os.sep.join([PATH,'config.json']))).read())
else:
SYS_ARGS['config'] = {}
if 'version' in SYS_ARGS['config'] :
_args['version'] = SYS_ARGS['config']['version']
version = check(**_args)
_version = {"current":0.0}if 'version' not in SYS_ARGS['config'] else SYS_ARGS['config']['version']
if _version['current'] != version['current'] :
print ()
print ("You need to upgrade your system to version to ",version['current'])
print ("\t- signup (for new configuration)")
print ("\t- use pip to upgrade the codebase")
else:
print ()
print ("You are running the current configuraiton version ",_version['current'])
except Exception as e:
print (e)
pass
elif 'export' in SYS_ARGS:
#
# this function is designed to export the data to csv
#
format = SYS_ARGS['format'] if 'format' in SYS_ARGS else 'csv'
format = format.lower()
if set([format]) not in ['xls','csv'] :
format = 'csv'
path = SYS_ARGS['config']
TYPE = SYS_ARGS['export'] if 'export' in SYS_ARGS else '835'
if not os.path.exists(path) or TYPE not in ['835','837']:
print (HELP_MESSAGE)
else:
#
# Let's run the export function ..., This will push files into a data-store of choice Redshift, PostgreSQL, MySQL ...
#
_store = {"type":"sql.SQLWriter","args":json.loads( (open(path) ).read())}
pipes = export.Factory.instance(type=TYPE,write_store=_store) #"inspect":0,"cast":0}})
# pipes[0].run()
for thread in pipes:
thread.start()
time.sleep(1)
while pipes :
pipes = [thread for thread in pipes if thread.is_alive()]
time.sleep(1)
else:
msg = """
cli:
healthcare-io.py --<[signup|init]> <email> --store <sqlite|mongo> [--batch <value>]
healthcare-io.py --parse claims --folder <path> [--batch <value>]
healthcare-io.py --parse remits --folder <path> [--batch <value>] [--resume]
parameters :
--<[signup|init]> signup or get a configuration file from a parsing server
--store data store mongo or sqlite or mongodb
--resume will attempt to resume if there was an interruption
"""
print(msg)
pass
# """
# The program was called from the command line thus we are expecting
# parse in [claims,remits]
# config os.sep.path.exists(path)
# folder os.sep.path.exists(path)
# store store ()
# """
# p = len( set(['store','config','folder']) & set(SYS_ARGS.keys())) == 3 and ('db' in SYS_ARGS or 'path' in SYS_ARGS)
# TYPE = {
# 'mongo':'mongo.MongoWriter',
# 'couch':'couch.CouchWriter',
# 'disk':'disk.DiskWriter'
# }
# INFO = {
# '837':{'scope':'claims','section':'HL'},
# '835':{'scope':'remits','section':'CLP'}
# }
# if p :
# args = {}
# scope = SYS_ARGS['config'][:-5].split(os.sep)[-1]
# CONTEXT = INFO[scope]['scope']
# #
# # @NOTE:
# # improve how database and data stores are handled.
# if SYS_ARGS['store'] == 'couch' :
# args = {'url': SYS_ARGS['url'] if 'url' in SYS_ARGS else 'http://localhost:5984'}
# args['dbname'] = SYS_ARGS['db']
# elif SYS_ARGS ['store'] == 'mongo':
# args = {'host':SYS_ARGS['host']if 'host' in SYS_ARGS else 'localhost:27017'}
# if SYS_ARGS['store'] in ['mongo','couch']:
# args['dbname'] = SYS_ARGS['db'] if 'db' in SYS_ARGS else 'claims_outcomes'
# args['doc'] = CONTEXT
# TYPE = TYPE[SYS_ARGS['store']]
# writer = factory.instance(type=TYPE,args=args)
# if SYS_ARGS['store'] == 'disk':
# writer.init(path = 'output-claims.json')
# logger = factory.instance(type=TYPE,args= dict(args,**{"doc":"logs"}))
# files = os.listdir(SYS_ARGS['folder'])
# CONFIG = json.loads(open(SYS_ARGS['config']).read())
# SECTION = INFO[scope]['section']
# for file in files :
# if 'limit' in SYS_ARGS and files.index(file) == int(SYS_ARGS['limit']) :
# break
# else:
# filename = os.sep.join([SYS_ARGS['folder'],file])
# try:
# content,logs = get_content(filename,CONFIG,SECTION)
# except Exception as e:
# if sys.version_info[0] > 2 :
# logs = [{"filename":filename,"msg":e.args[0]}]
# else:
# logs = [{"filename":filename,"msg":e.message}]
# content = None
# if content :
# writer.write(content)
# if logs:
# logger.write(logs)
# pass
# else:
# print (__doc__)
print(HELP_MESSAGE)

View File

@ -3,7 +3,78 @@ from healthcareio.params import SYS_ARGS
import healthcareio.analytics
import os
import json
import time
import smart
import transport
import pandas as pd
import numpy as np
from healthcareio import x12
from healthcareio.export import export
from multiprocessing import Process
# from flask_socketio import SocketIO, emit, disconnect,send
from healthcareio.server import proxy
PATH = os.sep.join([os.environ['HOME'],'.healthcareio','config.json'])
app = Flask(__name__)
# socket_ = SocketIO(app)
def resume (files):
_args = SYS_ARGS['config']['store'].copy()
if 'mongo' in SYS_ARGS['config']['store']['type'] :
_args['type'] = 'mongo.MongoReader'
reader = transport.factory.instance(**_args)
_files = []
try:
pipeline = [{"$match":{"completed":{"$eq":True}}},{"$group":{"_id":"$name"}},{"$project":{"name":"$_id","_id":0}}]
_args = {"aggregate":"logs","cursor":{},"allowDiskUse":True,"pipeline":pipeline}
_files = reader.read(mongo = _args)
_files = [item['name'] for item in _files]
except Exception as e :
pass
return list(set(files) - set(_files))
def run ():
#
# let's get the files in the folder (perhaps recursively traverse them)
#
FILES = []
BATCH = int(SYS_ARGS['config']['args']['batch']) #-- number of processes (poorly named variable)
for root,_dir,f in os.walk(SYS_ARGS['config']['args']['folder']) :
if f :
FILES += [os.sep.join([root,name]) for name in f]
FILES = resume(FILES)
FILES = np.array_split(FILES,BATCH)
procs = []
for FILE_GROUP in FILES :
FILE_GROUP = FILE_GROUP.tolist()
# logger.write({"process":index,"parse":SYS_ARGS['parse'],"file_count":len(row)})
# proc = Process(target=apply,args=(row,info['store'],_info,))
parser = x12.Parser(PATH) #os.sep.join([PATH,'config.json']))
parser.set.files(FILE_GROUP)
parser.start()
procs.append(parser)
SYS_ARGS['procs'] = procs
# @socket_.on('data',namespace='/stream')
def push() :
_args = dict(SYS_ARGS['config']['store'].copy(),**{"type":"mongo.MongoReader"})
reader = transport.factory.instance(**_args)
pipeline = [{"$group":{"_id":"$parse","claims":{"$addToSet":"$name"}}},{"$project":{"_id":0,"type":"$_id","count":{"$size":"$claims"}}}]
_args = {"aggregate":"logs","cursor":{},"allowDiskUse":True,"pipeline":pipeline}
r = pd.DataFrame(reader.read(mongo=_args))
r = healthcareio.analytics.Apex.apply({"chart":{"type":"donut","axis":{"x":"count","y":"type"}},"data":r})
# emit("update",r,json=True)
return r
# @socket_.on('connect')
# def client_connect(**r):
# print ('Connection received')
# print (r)
# push()
# pass
@app.route("/favicon.ico")
def _icon():
return send_from_directory(os.path.join([app.root_path, 'static','img','logo.svg']),
@ -12,7 +83,7 @@ def _icon():
def init():
e = SYS_ARGS['engine']
sections = {"remits":e.info['835'],"claims":e.info['837']}
_args = {"sections":sections}
_args = {"sections":sections,"store":SYS_ARGS["config"]["store"],"owner":SYS_ARGS['config']['owner'],"args":SYS_ARGS["config"]["args"]}
return render_template("index.html",**_args)
@app.route("/format/<id>/<index>",methods=['POST'])
def _format(id,index):
@ -21,43 +92,117 @@ def _format(id,index):
key = '837' if id == 'claims' else '835'
index = int(index)
# p = e.info[key][index]
p = e.apply(type=id,index=index)
#
p = e.filter(type=id,index=index)
r = []
for item in p[0]['pipeline'] :
_item= dict(item)
del _item['sql']
del _item ['data']
for item in p['pipeline'] :
_item= dict(item)
_item = dict(_item,**healthcareio.analytics.Apex.apply(item))
del _item['data']
if 'apex' in _item or 'html' in _item:
r.append(_item)
r = {"id":p[0]['id'],"pipeline":r}
r = {"id":p['id'],"pipeline":r}
return json.dumps(r),200
@app.route("/get/<id>/<index>",methods=['GET'])
def get(id,index):
e = SYS_ARGS['engine']
key = '837' if id == 'claims' else '835'
index = int(index)
# p = e.info[key][index]
p = e.apply(type=id,index=index)
p = e.filter(type=id,index=index)
r = {}
for item in p[0]['pipeline'] :
_item= [dict(item)]
r[item['label']] = item['data'].to_dict(orient='record')
# del _item['sql']
# del _item ['data']
# print (item['label'])
# _item['apex'] = healthcareio.analytics.Apex.apply(item)
# if _item['apex']:
# r.append(_item)
# r = {"id":p[0]['id'],"pipeline":r}
# r[item['label']] = item['data'].to_dict(orient='record')
r[item['label']] = item['data'].to_dict('record')
return json.dumps(r),200
@app.route("/reset",methods=["POST"])
def reset():
return "1",200
@app.route("/data",methods=['GET'])
def get_data ():
"""
This function will return statistical data about the services i.e general statistics about what has/been processed
"""
HEADER = {"Content-type":"application/json"}
_args = SYS_ARGS['config']
options = dict(proxy.get.files(_args),**proxy.get.processes(_args))
return json.dumps(options),HEADER
@app.route("/log/<id>",methods=["POST","PUT","GET"])
def log(id) :
HEADER = {"Content-Type":"application/json; charset=utf8"}
if id == 'params' and request.method in ['PUT', 'POST']:
info = request.json
_args = {"batch":info['batch'] if 'batch' in info else 1,"resume":True}
#
# We should update the configuration
SYS_ARGS['config']['args'] = _args
PATH = os.sep.join([os.environ['HOME'],'.healthcareio','config.json'])
write = lambda content: (open(PATH,'w')).write(json.dumps(content))
proc = Process(target=write,args=(SYS_ARGS['config'],))
proc.start()
return "1",HEADER
pass
@app.route("/io/<id>",methods=['POST'])
def io_data(id):
if id == 'params' :
_args = request.json
#
# Expecting batch,folder as parameters
_args = request.json
_args['resume'] = True
print (_args)
#
# We should update the configuration
SYS_ARGS['config']['args'] = _args
# PATH = os.sep.join([os.environ['HOME'],'.healthcareio','config.json'])
try:
write = lambda content: (open(PATH,'w')).write(json.dumps(content))
proc = Process(target=write,args=(SYS_ARGS['config'],))
proc.start()
# proc.join()
return "1",200
except Exception as e :
return "0",403
pass
elif id == 'stop' :
stop()
pass
elif id == 'run' :
# run()
_args = {"args":SYS_ARGS['config']['args'],"store":SYS_ARGS["config"]["store"]}
proxy.run(_args)
return "1",200
pass
@app.route("/export")
def export_form():
_args = {"context":SYS_ARGS['context']}
return render_template("store.html",**_args)
@app.route("/export",methods=['POST','PUT'])
def apply_etl():
_info = request.json
m = {'s3':'s3.s3Writer','mongo':'mongo.MongoWriter'}
if _info :
dest_args = {'type':m[_info['type']],"args": _info['content'] }
src_args = SYS_ARGS['config']['store']
# print (_args)
# writer = transport.factory.instance(**_args)
proxy.publish(src_args,dest_args)
return "1",405
else:
return "0",404
@app.route("/update")
def update():
pass
return "0",405
@app.route("/reload",methods=['POST'])
def reload():
# e = SYS_ARGS['engine']
@ -74,11 +219,20 @@ if __name__ == '__main__' :
PORT = int(SYS_ARGS['port']) if 'port' in SYS_ARGS else 5500
DEBUG= int(SYS_ARGS['debug']) if 'debug' in SYS_ARGS else 0
SYS_ARGS['context'] = SYS_ARGS['context'] if 'context' in SYS_ARGS else ''
#
#
PATH= SYS_ARGS['config'] if 'config' in SYS_ARGS else os.sep.join([os.environ['HOME'],'.healthcareio','config.json'])
#
# Adjusting configuration with parameters (batch,folder,resume)
if 'args' not in SYS_ARGS['config'] :
SYS_ARGS['config']["args"] = {"batch":1,"resume":True,"folder":"/data"}
SYS_ARGS['procs'] = []
# SYS_ARGS['path'] = os.sep.join([os.environ['HOME'],'.healthcareio','config.json'])
e = healthcareio.analytics.engine(PATH)
# e.apply(type='claims',serialize=True)
e.apply(type='claims',serialize=False)
SYS_ARGS['engine'] = e
app.run(host='0.0.0.0',port=PORT,debug=DEBUG,threaded=True)

View File

@ -12,8 +12,9 @@ def _icon():
def init():
e = SYS_ARGS['engine']
sections = {"remits":e.info['835'],"claims":e.info['837']}
_args = {"sections":sections}
return render_template("index.html",**_args)
_args = {"sections":sections,"store":SYS_ARGS['config']['store']}
print (SYS_ARGS['config']['store'])
return render_template("setup.html",**_args)
@app.route("/format/<id>/<index>",methods=['POST'])
def _format(id,index):

View File

@ -0,0 +1,170 @@
"""
This file serves as proxy to healthcare-io, it will be embedded into the API
"""
import os
import transport
import numpy as np
from healthcareio import x12
import pandas as pd
import smart
from healthcareio.analytics import Apex
import time
class get :
PROCS = []
PATH = os.sep.join([os.environ['HOME'],'.healthcareio','config.json'])
@staticmethod
def resume (files,args):
"""
This function will determine the appropriate files to be processed by performing a simple complementary set operation against the logs
@TODO: Support data-stores other than mongodb
:param files list of files within a folder
:param _args configuration
"""
_args = args['store'].copy()
if 'mongo' in _args['type'] :
_args['type'] = 'mongo.MongoReader'
reader = transport.factory.instance(**_args)
_files = []
try:
pipeline = [{"$match":{"completed":{"$eq":True}}},{"$group":{"_id":"$name"}},{"$project":{"name":"$_id","_id":0}}]
_args = {"aggregate":"logs","cursor":{},"allowDiskUse":True,"pipeline":pipeline}
_files = reader.read(mongo = _args)
_files = [item['name'] for item in _files]
except Exception as e :
pass
print ( [len(list(set(files) - set(_files))),' files to be processed'])
return list(set(files) - set(_files))
@staticmethod
def processes(_args):
_info = pd.DataFrame(smart.top.read(name='healthcare-io.py'))[['name','cpu','mem']]
if _info.shape[0] == 0 :
_info = pd.DataFrame({"name":["healthcare-io.py"],"cpu":[0],"mem":[0]})
# _info = pd.DataFrame(_info.groupby(['name']).sum())
# _info['name'] = ['healthcare-io.py']
m = {'cpu':'CPU','mem':'RAM','name':'name'}
_info.columns = [m[name] for name in _info.columns.tolist()]
_info.index = np.arange(_info.shape[0])
charts = []
for label in ['CPU','RAM'] :
value = _info[label].sum()
df = pd.DataFrame({"name":[label],label:[value]})
charts.append (
Apex.apply(
{"data":df, "chart":{"type":"radial","axis":{"x":label,"y":"name"}}}
)['apex']
)
#
# This will update the counts for the processes, upon subsequent requests so as to show the change
#
N = 0
lprocs = []
for proc in get.PROCS :
if proc.is_alive() :
lprocs.append(proc)
N = len(lprocs)
get.PROCS = lprocs
return {"process":{"chart":charts,"counts":N}}
@staticmethod
def files (_args):
_info = smart.folder.read(path='/data')
N = _info.files.tolist()[0]
if 'mongo' in _args['store']['type'] :
store_args = dict(_args['store'].copy(),**{"type":"mongo.MongoReader"})
# reader = transport.factory.instance(**_args)
pipeline = [{"$group":{"_id":"$name","count":{"$sum":{"$cond":[{"$eq":["$completed",True]},1,0]}} }},{"$group":{"_id":None,"count":{"$sum":"$count"}}},{"$project":{"_id":0,"status":"completed","count":1}}]
query = {"mongo":{"aggregate":"logs","allowDiskUse":True,"cursor":{},"pipeline":pipeline}}
# _info = pd.DataFrame(reader.read(mongo={"aggregate":"logs","allowDiskUse":True,"cursor":{},"pipeline":pipeline}))
pipeline = [{"$group":{"_id":"$parse","claims":{"$addToSet":"$name"}}},{"$project":{"_id":0,"type":"$_id","count":{"$size":"$claims"}}}]
_query = {"mongo":{"aggregate":"logs","cursor":{},"allowDiskUse":True,"pipeline":pipeline}} #-- distribution claims/remits
else:
store_args = dict(_args['store'].copy(),**{"type":"disk.SQLiteReader"})
store_args['args']['table'] = 'logs'
query= {"sql":"select count(distinct json_extract(data,'$.name')) as count, 'completed' status from logs where json_extract(data,'$.completed') = true"}
_query={"sql":"select json_extract(data,'$.parse') as type,count(distinct json_extract(data,'$.name')) as count from logs group by type"} #-- distribution claim/remits
reader = transport.factory.instance(**store_args)
_info = pd.DataFrame(reader.read(**query))
if not _info.shape[0] :
_info = pd.DataFrame({"status":["completed"],"count":[0]})
_info['count'] = np.round( (_info['count'] * 100 )/N,2)
charts = [Apex.apply({"data":_info,"chart":{"type":"radial","axis":{"y":"status","x":"count"}}})['apex']]
#
# Let us classify the files now i.e claims / remits
#
# pipeline = [{"$group":{"_id":"$parse","claims":{"$addToSet":"$name"}}},{"$project":{"_id":0,"type":"$_id","count":{"$size":"$claims"}}}]
# _args = {"aggregate":"logs","cursor":{},"allowDiskUse":True,"pipeline":pipeline}
# r = pd.DataFrame(reader.read(mongo=_args))
r = pd.DataFrame(reader.read(**_query)) #-- distribution claims/remits
r = Apex.apply({"chart":{"type":"donut","axis":{"x":"count","y":"type"}},"data":r})['apex']
r['chart']['height'] = '100%'
r['legend']['position'] = 'bottom'
charts += [r]
return {"files":{"counts":N,"chart":charts}}
pass
#
# Process handling ....
def run (_args) :
"""
This function will run the jobs and insure as processes (as daemons).
:param _args system configuration
"""
FILES = []
BATCH = int(_args['args']['batch']) #-- number of processes (poorly named variable)
for root,_dir,f in os.walk(_args['args']['folder']) :
if f :
FILES += [os.sep.join([root,name]) for name in f]
FILES = get.resume(FILES,_args)
FILES = np.array_split(FILES,BATCH)
for FILE_GROUP in FILES :
FILE_GROUP = FILE_GROUP.tolist()
# logger.write({"process":index,"parse":_args['parse'],"file_count":len(row)})
# proc = Process(target=apply,args=(row,info['store'],_info,))
parser = x12.Parser(get.PATH) #os.sep.join([PATH,'config.json']))
parser.set.files(FILE_GROUP)
parser.daemon = True
parser.start()
get.PROCS.append(parser)
time.sleep(3)
#
# @TODO:consider submitting an update to clients via publish/subscribe framework
#
return get.PROCS
def stop(_args):
for job in get.PROCS :
if job.is_alive() :
job.terminate()
get.PROCS = []
#
# @TODO: consider submitting an update to clients via publish/subscribe framework
pass
def write(src_args,dest_args,files) :
#
# @TODO: Support for SQLite
pass
def publish (src_args,dest_args,folder="/data"):
FILES = []
for root,_dir,f in os.walk(folder) :
if f :
FILES += [os.sep.join([root,name]) for name in f]
#
# @TODO: Add support for SQLite ....
FILES = np.array_split(FILES,4)

View File

@ -1,3 +1,4 @@
.active {
padding:4px;
cursor:pointer;
@ -6,3 +7,51 @@
.active:hover{
border-bottom:2px solid #ff6500;
}
input[type=text]{
border:1px solid transparent;
background-color:#f3f3f3;
outline: 0px;
padding:8px;
font-weight:normal;
font-family:sans-serif;
color:black;
}
.active-button {
display:grid;
grid-template-columns: 32px auto;
gap:2px;
align-items:center;
border:2px solid #CAD5E0;
cursor:pointer;
}
.active-button i {padding:4px;;}
.active-button:hover { border-color:#ff6500}
.system {display:grid; grid-template-columns: 45% 1px auto; gap:20px; margin-left:5%; width:90%;}
.system .status .item {display:grid; grid-template-columns: 75px 8px auto; gap:2px;}
.input-form {display:grid; gap:2px;}
.input-form .item {display:grid; grid-template-columns: 125px auto; gap:2px; align-items:center;}
.input-form .item .label { font-weight:bold; padding-left:10px}
.fa-cog {color:#4682B4}
.fa-check {color:#00c6b3}
.fa-times {color:maroon}
.code {
margin:4px;
background:#000000 ;
padding:8px;
font-family: 'Courier New', Courier, monospace;
color:#d3d3d3;
font-size:12px;
line-height: 2;
}
.tabs {display:grid; grid-template-columns: repeat(3,1fr) auto; gap:0px; align-items:center; text-align: center;}
.tab {border:1px solid transparent; border-bottom-color:#D3D3D3; font-weight:bold; padding:4px}
.tabs .selected {border-color:#CAD5E0; border-bottom-color:transparent; }
.system iframe {width:100%; height:100%; border:1px solid transparent;}
.data-info {height:90%; padding:8px;}
.fa-cloud {color:#4682B4}
.fa-database{color:#cc8c91}

View File

@ -0,0 +1,21 @@
<div class="dialog">
<div class="title-bar">
<div class="title bold" ></div>
<div class="active close" align="center"><i class="fas fa-times"></i></div>
</div>
<div class="message">
<div class="icon" align="center">
<i id="msg-icon"></i>
</div>
<div class="text"></div>
</div>
<div class="action">
<div class="active-button border-round" align="center">
<div align="center">
<i class="fas fa-check"></i>
</div>
<div class="bold">Ok</div>
</div>
</div>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,75 @@
/***
* This file will handle the dialog boxes as they and their associated configurations and function binding
*/
if (!dialog){
var dialog = {}
}
dialog.open = function(title,msg,pointer){
if (sessionStorage.dialog == null){
var http = HttpClient.instance()
http.get(sessionStorage.io_context+'/static/dialog.html',function(x){
var html = x.responseText
jx.modal.show({html:html,id:'dialog'})
$('.dialog .title').text(title)
$('.dialog .message .text').text(msg)
dialog.status.ask()
$('.dialog .action .active-button').on('click',pointer)
$('.dialog .title-bar .close').on('click',function(){dialog.close(0)})
})
}else{
var html = sessionStorage.dialog
jx.modal.show({html:html,id:'dialog'})
dialog.status.ask()
$('.dialog .action .active-button').on('click',pointer)
$('.dialog .title-bar .close').on('click',function(){dialog.close(0)})
}
}
dialog.bind = function(pointer){
if (pointer == null){
pointer = dialog.close
}
$('.dialog .action .active-button').off()
$('.dialog .action .active-button').on('click',pointer)
}
dialog.close = function(delay){
delay = (delay == null)?1750:delay
setTimeout(function(){
if ( $('.dialog').length > 0){
jx.modal.close()
}
},delay)
}
dialog.status = {}
dialog.status.wait = function(){
$('.dialog .action .active-button').hide()
}
dialog.status.confirm = function(){
$('.dialog .action .active-button').show()
}
dialog.status.busy = function(){
$('.dialog .message #msg-icon').removeClass()
$('.dialog .message #msg-icon').addClass('fas fa-cog fa-4x fa-spin')
}
dialog.status.fail = function(){
$('.dialog .message #msg-icon').removeClass()
$('.dialog .message #msg-icon').addClass('fas fa-times fa-4x')
}
dialog.status.ask = function(){
$('.dialog .message #msg-icon').removeClass()
$('.dialog .message #msg-icon').addClass('far fa-question-circle fa-4x')
}
dialog.status.warn = function(){
$('.dialog .message #msg-icon').removeClass()
$('.dialog .message #msg-icon').addClass('fas fa-exclamation-triangle fa-4x')
}
dialog.status.success = function(){
$('.dialog .message #msg-icon').removeClass()
$('.dialog .message #msg-icon').addClass('fas fa-check fa-4x')
}

View File

@ -0,0 +1,15 @@
if (!healthcare) {
var healthcare = {io:{}}
}
healthcare.io = {'dialog':dialog,'confirmed':confirmed,'reset':reset,'update':update,'run':run,'publish':publish}
healthcare.io.apply = function(){
var value = $('.input-form .item .procs').val()
var folder= $('.input-form .item .folder').val()
$('.code .batch').html(value)
var http = HttpClient.instance()
http.setData({"batch":value,"resume":true,"folder":folder},"application/json")
http.post(sessionStorage.io_context+'/io/params',function(x){})
}

View File

@ -0,0 +1,182 @@
/**
* This file will depend on dialog.js (soft dependency). Some functions here will make calls to resources in dialog.js
*/
var reset = function(){
dialog.open('Healthcare/IO::Parser', 'Are you sure you would like to delete all data parsed? Click Ok to confirm',confirmed.reset)
}
var update= function(){
dialog.open('Healthcare/IO::Parser','Update will change parsing configuration. Would you like to continue ?',confirmed.update)
}
var run = function(){
dialog.open('Healthcare/IO::Parser','Preparing parser, confirm to continue',confirmed.run)
}
var _queue = {socket:null}
var confirmed = {}
confirmed.run = function(){
dialog.status.busy()
dialog.status.wait()
$('.dialog .message .text').html('Initiating Parsing ...')
setTimeout(function(){
var http = HttpClient.instance()
http.post(sessionStorage.io_context+'/io/run',function(x){
// dialog.handler = setInterval(function(){monitor.data()},750)
monitor.data()
//dialog.close()
})
},1000)
}
confirmed.reset = function(){
var uri = sessionStorage.io_context+'/reset'
var http= HttpClient.instance()
dialog.status.busy()
dialog.status.wait()
http.post(uri,function(x){
setTimeout(function(){
if (x.status == 200 && x.responseText == "1"){
dialog.status.success()
$('.dialog .message .text').html('Reset Healthcare/IO::Parser was successful!<br><div align="center">Dialog will be closing</div>')
dialog.close()
}else{
dialog.status.fail()
}
},2000)
})
}
confirmed.update = function(){
var uri = sessionStorage.io_context+'/update'
var email = $('#email').val()
//
//-- validate the email
if (email.match(/^([^\s]+)@([^\s@]+)\.(org|com|edu|io)$/i)){
dialog.status.wait()
dialog.status.busy()
var http = HttpClient.instance()
http.setData({"email":email},"application/son")
setTimeout(function(){
http.post(uri,function(x){
if(x.status == 200 && x.responseText == "1"){
dialog.status.success()
}else{
dialog.status.fail()
$('.dialog .message .text').html('Error code '+x.status)
dialog.bind()
dialog.status.confirm()
$('.dialog .title-bar .title').html("Error found")
}
})
},1000)
}else{
dialog.status.fail()
dialog.bind()
$('.dialog .title-bar .title').text("Error found")
$('.dialog .message .text').html('Invvalid Email entered')
dialog.status.confirm()
}
}
/**
* This namespace is designed to export data to either the cloud or to a database
*/
var publish={set:{}}
publish.post = function(){
if($('.jxmodal').length > 0){
jx.modal.close()
}
dialog.open('Export/ETL','Please wait')
dialog.status.busy()
var http = HttpClient.instance()
http.setData(JSON.parse(sessionStorage.export),"application/json")
http.post(sessionStorage.io_context+'/export',function(x){
if (x.status != 200){
setTimeout(function(){
$('.dialog .message .text').html('An error occurred with code '+x.status)
dialog.status.fail()
dialog.status.wait()
},1500)
}
//
// @TODO: Have progress be monitored for this bad boy i.e open the connection to socket and read in ...
//
})
}
publish.set.file = function(){
var file = $('#file')[0].files[0]
$('.file .name').html(file.name)
var button = $('.cloud input').prop('disabled',true)
var div = $('.cloud .file .fa-file-upload')[0]
$(div).empty()
$(div).addClass('fas fa-cog fa-spin')
var reader = new FileReader()
reader.readAsText(file)
reader.onload = function(){
_args = {"type":$('.cloud .id').html().trim(),"content":reader.result}
// _args = JSON.stringify(_args)
if (_args.content.match(/^\{.+/i) == null){
content = _args.content.split('\n')[1].split(',')
_args.content = {'bucket':'healthcareio','access_key':content[0].trim(),'secret_key':content[1].trim()}
}
sessionStorage.export = JSON.stringify(_args)
}
reader.onloadend = function(){
setTimeout(function(){
var div = $('.cloud .file .fa-cog')[0]
$(div).empty()
$(div).addClass('fas fa-check')
$(div).removeClass('fa-spin')
// jx.modal.close()
//setTimeout(jx.modal.close,1500)
publish.post()
},2000)
}
}
publish.database = {}
publish.database.init = function(id){
//
// we are expecting id in {mongo,couch,postgresql,mysql,sqlite}
// @TODO: Account for cloud service brokers like dropbox, box, one-drive and google-drive
sessionStorage.export = "{}"
p = {'id':id}
if (id.match(/(mongodb|postgresql|mysql|sqlite|couchdb)/i)){
var hide_id = '.store .cloud'
var show_id = '.store .database'
}else{
//
// @TODO: generate an error message
var show_id = '.store .cloud'
var hide_id = '.store .database'
}
var http = HttpClient.instance()
http.get(sessionStorage.io_context+'/export',function(x){
var html = x.responseText
jx.modal.show({'html':html,'id':'dialog'})
$(hide_id).hide(function(){
$(show_id).show()
})
$('.store .id').text(id)
})
}

View File

@ -12,119 +12,128 @@
* Improve on how returned data is handled (if necessary).
*/
if(!jx){
var jx = {}
}
/**
* These are a few parsers that can come in handy:
* urlparser: This parser is intended to break down a url parameter string in key,value pairs
*/
function urlparser(url){
if(url.toString().match(/\x3F/) != null){
url = url.split('\x3F')[1]
}
var p = url.split('&') ;
var r = {} ;
r.meta = [] ;
r.data = {} ;
var entry;
for(var i=0; i < p.length; i++){
entry = p[i] ;
key = (entry.match('(.*)=') !=null)? entry.match('(.*)=')[1]:null ;
value = (entry.match('=(.*)$') != null)? entry.match('=(.*)$')[1]:null
if(key != null){
key = key.replace('\x3F','')
r.meta.push(key) ;
r.data[key] = value ;
}
}
return r.data;
}
/**
* The following are corrections related to consistency in style & cohesion
*/
jx.ajax = {}
jx.ajax.get = {} ;
jx.ajax.debug = null;
jx.ajax.get.instance = function(){
var factory = function(){
this.obj = {}
this.obj.headers = {}
this.obj.async = true;
this.setHeader = function(key,value){
if(key.constructor != String && value == null){
this.obj.headers = key ;
}else{
this.obj.headers[key] = value;
}
}
this.setData = function(data){
this.obj.data = data;
}
this.setAsync = function(flag){
this.obj.async = (flag == true) ;
}
this.send = function(url,callback,method){
if(method == null){
method = 'GET'
}
p = jx.ajax.debug != null;
q = false;
if(p){
q = jx.ajax.debug[url] != null;
}
is_debuggable = p && q
if(is_debuggable){
x = {} ;
x.responseText = jx.ajax.debug [url] ;
callback(x)
}else{
var http = new XMLHttpRequest() ;
http.onreadystatechange = function(){
if(http.readyState == 4){
callback(http)
}
}
//
// In order to insure backward compatibility
// Previous versions allowed the user to set the variable on the wrapper (poor design)
if(this.async != null){
this.setAsync(this.async) ;
}
http.open(method,url,this.obj.async) ;
for(key in this.obj.headers){
value = this.obj.headers[key] ;
http.setRequestHeader(key,value)
}
http.send(this.obj.data)
}
}
this.put = function(url,callback){
this.send(url,callback,'PUT') ;
}
this.get = function(url,callback){
this.send(url,callback,'GET') ;
}
this.post = function(url,callback){
this.send(url,callback,'POST') ;
}
}//-- end of the factory method
return new factory() ;
}
//
// backward compatibility
jx.ajax.getInstance = jx.ajax.get.instance ;
var HttpClient = jx.ajax.get ;
var jx = {}
}
/**
* These are a few parsers that can come in handy:
* urlparser: This parser is intended to break down a url parameter string in key,value pairs
*/
function urlparser(url){
if(url.toString().match(/\x3F/) != null){
url = url.split('\x3F')[1]
}
var p = url.split('&') ;
var r = {} ;
r.meta = [] ;
r.data = {} ;
var entry;
for(var i=0; i < p.length; i++){
entry = p[i] ;
key = (entry.match('(.*)=') !=null)? entry.match('(.*)=')[1]:null ;
value = (entry.match('=(.*)$') != null)? entry.match('=(.*)$')[1]:null
if(key != null){
key = key.replace('\x3F','')
r.meta.push(key) ;
r.data[key] = value ;
}
}
return r.data;
}
/**
* The following are corrections related to consistency in style & cohesion
*/
jx.ajax = {}
jx.ajax.get = {} ;
jx.ajax.debug = null;
jx.ajax.get.instance = function(){
var factory = function(){
this.obj = {}
this.obj.headers = {}
this.obj.async = true;
this.setHeader = function(key,value){
if(key.constructor != String && value == null){
this.obj.headers = key ;
}else{
this.obj.headers[key] = value;
}
}
this.setData = function(data,mimetype){
if(mimetype == null)
this.obj.data = data;
else {
this.obj.headers['Content-Type'] = mimetype
if(mimetype.match(/application\/json/i)){
this.obj.data = JSON.stringify(data)
}
}
}
this.setAsync = function(flag){
this.obj.async = (flag == true) ;
}
this.send = function(url,callback,method){
if(method == null){
method = 'GET'
}
p = jx.ajax.debug != null;
q = false;
if(p){
q = jx.ajax.debug[url] != null;
}
is_debuggable = p && q
if(is_debuggable){
x = {} ;
x.responseText = jx.ajax.debug [url] ;
callback(x)
}else{
var http = new XMLHttpRequest() ;
http.onreadystatechange = function(){
if(http.readyState == 4){
callback(http)
}
}
//
// In order to insure backward compatibility
// Previous versions allowed the user to set the variable on the wrapper (poor design)
if(this.async != null){
this.setAsync(this.async) ;
}
http.open(method,url,this.obj.async) ;
for(key in this.obj.headers){
value = this.obj.headers[key] ;
http.setRequestHeader(key,value)
}
http.send(this.obj.data)
}
}
this.put = function(url,callback){
this.send(url,callback,'PUT') ;
}
this.get = function(url,callback){
this.send(url,callback,'GET') ;
}
this.post = function(url,callback){
this.send(url,callback,'POST') ;
}
}//-- end of the factory method
return new factory() ;
}
//
// backward compatibility
jx.ajax.getInstance = jx.ajax.get.instance ;
var HttpClient = jx.ajax.get ;

View File

@ -0,0 +1,29 @@
<meta charset="utf8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<link rel="shortcut icon" href="{{context}}/static/img/logo.svg" type="image/icon type">
<link rel="stylesheet" href="{{context}}/static/css/default.css" type="text/css">
<script src="{{context}}/static/js/jx/rpc.js"></script>
<script src="{{context}}/static/js/jx/dom.js"></script>
<script src="{{context}}/static/js/jx/utils.js"></script>
<script src="{{context}}/static/js/jquery.js"></script>
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<link href="{{context}}/static/css/borders.css" type="text/css" rel="stylesheet">
<link href="{{context}}/static/css/fa/css/all.css" type="text/css" rel="stylesheet">
<script src="{{context}}/static/css/fa/js/all.js"></script>
<div class="border-round border menu-bar">
<div class="menu">
Admin
<div class="menu-items border">
<div class="item">Setup</div>
</div>
</div>
<div class="menu">
Claims & Remits
</div>
</div>

View File

@ -8,6 +8,7 @@
<script src="{{context}}/static/js/jx/rpc.js"></script>
<script src="{{context}}/static/js/jx/dom.js"></script>
<script src="{{context}}/static/js/jx/utils.js"></script>
<script src="{{context}}/static/js/jx/ext/modal.js"></script>
<script src="{{context}}/static/js/jquery.js"></script>
@ -15,6 +16,9 @@
<link href="{{context}}/static/css/borders.css" type="text/css" rel="stylesheet">
<link href="{{context}}/static/css/fa/css/all.css" type="text/css" rel="stylesheet">
<script src="{{context}}/static/css/fa/js/all.js"></script>
<script src="{{context}}/static/js/io/dialog.js"></script>
<script src="{{context}}/static/js/io/io.js"></script>
<script src="{{context}}/static/js/io/healthcare.js"></script>
<style>
body {
font-size:16px;
@ -64,6 +68,7 @@
scroll-behavior: smooth;
gap:2px;
padding:4px;
height:95%;
}
@ -81,12 +86,12 @@
}
.dashboard .chart-pane .chart {
.dashboard .chart-pane .chart2 {
max-height:99%;
min-height:99%;
height:99%;
}
.dashboard .chart-pane .chart .graph {
.dashboard .chart-pane .chart2 .graph {
max-height:100%;
@ -95,7 +100,7 @@
}
.dashboard .chart-pane .chart .graph .apexcharts-svg {
.dashboard .chart-pane .chart2 .graph .apexcharts-svg {
/*border-radius:8px;*/
background-color:#f3f3f3;
max-height:100%;
@ -161,7 +166,7 @@
}
.gradient { background-image: linear-gradient(to top,#F3F3F3, #D3D3D3, #F3F3F3);}
.gradient { background-image: linear-gradient(to top,#F3F3F3, #FFFFFF, #FFFFFF);}
.white {color:#ffffff}
.scalar {
display:grid;
@ -172,23 +177,39 @@
}
.shadow {
box-shadow: 0px 4px 4px #d3d3d3;
}
.scalar-title { padding:8px; text-transform: capitalize; }
.scalar .value {font-size:32px; font-weight:bold; margin:4%;}
.scalar .value {font-size:32px; margin:4%;}
.scalar .label {font-size:12px; text-transform:capitalize; text-overflow: ellipsis; display:grid; align-items: flex-end; text-align:center ;}
.monthly_patient_count, .taxonomy_code_distribution, .top_adjustment_codes, .adjustment_reasons {
grid-row:1 / span 3 ;
}
</style>
<script>
sessionStorage.io_context = "{{context}}"
var plot = function(id,index){
$('.system').slideUp(function(){
$('.dashboard').slideDown()
})
var uri = ([sessionStorage.io_context,'format',id,index]).join('/')
var httpclient = HttpClient.instance()
//
// @TODO: Let the user know something is going on .. spinner
httpclient.post(uri,function(x){
var r = JSON.parse(x.responseText)
var pane = jx.dom.get.instance('DIV')
var scalar_pane = jx.dom.get.instance('DIV')
pane.id = r.id
@ -202,9 +223,9 @@
var p = jx.utils.patterns.visitor(r.pipeline,function(item){
var div = jx.dom.get.instance('DIV')
var frame = jx.dom.get.instance('DIV')
//div.className = 'chart border-round border'
frame.className = 'chart border'
div.className = 'graph'
//div.className = 'chart2 border-round border'
frame.className = 'chart2 border ' + item.label.toLowerCase().replace(/ /g,'_')
div.className = 'graph '
//frame.append(div)
//pane.append(frame)
@ -212,8 +233,11 @@
if(item.apex != null){ item.apex.title = {text:item.label}
frame.append(div)
pane.append(frame)
delete item.apex.colors
item.apex.theme= {
if (item.apex.colors ){
delete item.apex.colors
}
/*item.apex.theme= {
mode: 'material',
palette: 'palette6',
monochrome: {
@ -222,8 +246,11 @@
shadeTo: 'light',
shadeIntensity: 0.65
},
}
}*/
item.apex.chart.height = '100%'
delete item.apex.chart.width
return new ApexCharts(div,item.apex)
}else{
//frame.className = ''
@ -283,50 +310,80 @@
}
}
$(document).ready(function(){
$('.dashabord').hide()
$('.item-group').slideUp()
var index = 0;
jx.utils.patterns.visitor($('.menu .items'), function(_item){
var node = $(_item).children()[0]
$(node).attr('index',index)
node.onclick = function(){ toggle($(this).attr('index')) }
index += 1;
})
var year = (new Date()).getFullYear()
$('.year').text(year)
})
</script>
<title>Healthcare/IO Analytics</title>
<body>
<div class="pane border">
<div class="pane">
<div class="header border-bottom">
<div class="caption">Healthcare/IO</div>
<div class="small">Analytics Dashboard</div>
<div class="caption">Healthcare/IO :: Parser</div>
<div class="small">Dashboard</div>
</div>
<div class="menu border-right">
<div class="menu">
<div>
{% for key in sections %}
<div class="items">
<div class="bold active" onclick="toggle({{loop.index -1}})" style="margin:4px; height:28px; display:grid; gap:2px; grid-template-columns:auto 32px;">
<div>{{key|safe}}</div>
<div align="center" class="glyph" >
<i class="fas fa-angle-down"></i>
<div class="items">
<div class="bold active" style="margin:4px; height:28px; display:grid; gap:2px; grid-template-columns:auto 32px;">
<div>Setup</div>
<div align="center" class="glyph" >
<i class="fas fa-angle-down"></i>
</div>
</div>
<div class="item-group border border-round">
<div class="item small active" onclick="setup.open()">Configure Parser</div>
<div class="item small active" onclick="healthcare.io.reset()">Reset Parser</div>
</div>
</div>
<div class="item-group border">
{% for item in sections[key] %}
<div class="item small active" onclick="plot('{{key}}',{{loop.index-1}})">{{item.id}}</div>
{% endfor %}
</div>
</div>
{% endfor %}
{% for key in sections %}
<div class="items">
<div class="bold active" style="margin:4px; height:28px; display:grid; gap:2px; grid-template-columns:auto 32px;">
<div>{{key|safe}}</div>
<div align="center" class="glyph" >
<i class="fas fa-angle-down"></i>
</div>
</div>
<div class="item-group border border-round">
{% for item in sections[key] %}
<div class="item small active" onclick="plot('{{key}}',{{loop.index-1}})">{{item.id}}</div>
{% endfor %}
</div>
</div>
{% endfor %}
</div>
<div style="display:grid; align-items:flex-end">
<div class="logs border" style="height:250px"></div>
<div style="display:none; align-items:flex-end">
<div class="logs chart" style=" align-items:center; display:grid" align="center"></div>
</div>
</div>
<div class="dashboard">
<div>
<div class="dashboard" style="display:none"></div>
</div>
{%include 'setup.html' %}
</div>
</div>
<div class="footer small">
&copy; Vanderbilt University Medical Center
Healthcare/IO :: Parser &copy; <span class="year"> </span>
</div>
</body>

View File

@ -0,0 +1,391 @@
<style>
.system {height:99%; overflow:hidden;}
.data-info .board{ height:300px; display:grid; grid-template-columns:auto 200px 200px; gap:20px; align-items:center}
/*.board { background-image: linear-gradient(to bottom, #ffffff,#ffffff,#f3f3f3,#d3d3d3d3)}*/
.number {font-size:48px; font-family:courier;padding:8px; ;}
.etl {display:grid; grid-template-columns: 250px auto; gap:2;}
.chart {box-shadow : 0px 1px 4px 2px #d3d3d3; width:200px; height:250px;
display:grid; align-items:center;
background-image: linear-gradient(to bottom,#f3f3f3,#ffffff);
overflow:hidden;
}
.dialog { width:450px; min-height:200px; display:grid; grid-template-rows: 40px 80% auto; gap:4px}
.dialog .title-bar { border-top-left-radius: 8px; border-top-right-radius: 8px ; padding:4px; background-color:#f3f3f3; gap:2px; display:grid; grid-template-columns: auto 32px; align-items:center}
.dialog .action {display:grid; align-items: flex-end; padding-left:25%; padding-right:25%;}
.dialog .message {display:grid; align-items: center; grid-template-columns: 20% auto;}
.dialog .message .text {line-height:2; text-transform: capitalize;}
.fa-exclamation-triangle {color:orange}
.fa-question-circle{color:#009df7}
</style>
<script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>
<script src="{{context}}/static/js/io/dialog.js"></script>
<script src="{{context}}/static/js/io/io.js"></script>
<script src="{{context}}/static/js/io/healthcare.js"></script>
<script>
var select = function(node){
var value = $($(node).children()[0]).attr('data-value')
jx.utils.patterns.visitor($('.tab'),function(_item){
var button = $(_item).children()[0]
$(_item).removeClass('selected')
//alert([$(button).attr('data-value'),value])
if($(button).attr('data-value') == value){
$(node).addClass('selected')
$('.'+value).show()
}else{
var m = '.'+ $(button).attr('data-value')
$(m).hide()
}
})
}
var monitor = {}
monitor.listen = {handler:null}
monitor.data = function(){
var http = HttpClient.instance()
http.get("/data",function(x){
var r = JSON.parse(x.responseText)
var keys = jx.utils.keys(r) //-- process,files
for (var i in keys){
var prefix = keys[i]
if(prefix == 'process'){
if(r[prefix].counts != 0){
//
// We should insure the listeners are enabled
if(monitor.listen.handler == null){
monitor.listen.handler = setInterval(
function(){
console.log('running ...')
monitor.data()},5000)
}
}else{
if (monitor.listen.handler != null){
clearInterval(monitor.listen.handler)
}
dialog.close()
}
}
monitor.render(prefix,r[prefix])
}
})
}
monitor.render = function(prefix,r){
prefix = '.'+prefix
var div = jx.dom.get.instance('DIV')
var label = jx.dom.get.instance('DIV')
div.align = 'center'
div.innerHTML = r.counts
div.className = 'number'
label.innerHTML = prefix.replace(/\./,'')
label.style.textTransform = 'capitalize'
label.className = 'small bold border-top'
div.append(label)
$(prefix + ' .board').empty()
$(prefix+' .board').append(div)
var charts = jx.utils.patterns.visitor(r.chart,function(option){
var div = jx.dom.get.instance('div')
div.className = 'chart'
div.align='center'
$(prefix+' .board').append(div)
var chart = new ApexCharts($(div)[0],option)
//chart.render()
div.chart = chart
return chart
})
var observers = jx.utils.patterns.visitor(charts,function(_item){
var m = function(_chart){
this.chart = _chart ;
this.apply = function(caller){this.chart.render();
caller.notify()
}
}
return new m(_item)
})
jx.utils.patterns.observer(observers,'apply')
//jx.utils.patterns.iterator(charts,'render')
/*setTimeout(function(){
jx.utils.patterns.visitor(charts,function(_item){_item.render()})
},1000) */
}
var setup = {}
setup.open = function(){
$('.dashboard').slideUp(
function(){
$('.setup').slideDown()
}
)
}
$(document).ready(function(){
/*var shandler = new io();
if (shandler.disconnected ==false){
shandler.disconnect()
}
var socket = io.connect()
socket.on('connect',function(e){
socket.emit('connect',{name:'steve'})
})
socket.on('update',function(e){
console.log(e)
console.log()
})
var socket = io.connect('http://localhost:81',{cors:{AccessControlAllowOrigin:'*'}}) //('http://localhost:81/stream')
socket.on('procs',function(e){
})
socket.on('data',function(e){
$('.logs').empty()
var div = $('.logs')
var option = e.apex
option.plotOptions.pie.size = 220
option.plotOptions.pie = {dataLabels: {show:true,name:{show:true},value:{show:true}}}
option.legend.show = false
console.log(option)
c = new ApexCharts(div[0],option)
c.render()
socket.emit("procs",{"name":"steve"})
})*/
select($('.tab')[0])
monitor.data()
$('.email').text($('#email').val())
})
</script>
<div class="system setup">
<div class="status">
{% if not store.type %}
<div >
<span class="caption bold border-bottom" style="padding-right:10">Current Configuration</span>
<p></p>
<div style="display:grid; align-items:center; grid-template-columns:32px auto;">
<i class="fa fa-times" style="font-size:28; margin:4px;"></i> <span>System needs to be initialized !</span>
</div>
<p></p>
<div class="active-button border-round" style="width:50%">
<div class="icon">
<i class="fas fa-cog" style="font-size:28"></i>
</div>
<div class="bold" align="center">Initialize</div>
</div>
</div>
{% else %}
<div class="border-right">
<span class="caption bold border-bottom" style="padding-right:10">Current Configuration</span>
<p>
</p>
<div class="item" style="display:grid; align-items:center">
<div class="bold" style="text-transform: capitalize;">Owner </div><div class="bold">:</div>
<div>
<input type="text" id="email" value="{{owner}}">
</div>
</div>
<div class="item">
<div class="bold" style="text-transform: capitalize;">store</div><div class="bold">:</div>
<div class="">{{store.type}}</div>
</div>
<p></p>
<div class="active-button border-round" style="width:50%" onclick="healthcare.io.update()">
<div class="icon">
<I class="fas fa-download" style="font-size:28"></I>
</div>
<div class="bold" align="center">Update Config</div>
</div>
<p>
<div class="code">
#<br>
healthcare-io.py --init <span class="email"></span> --store mongo
</div>
</p>
</div>
{%endif%}
<p></p>
<br>
<div class="border-right">
<span class="caption bold border-bottom" style="padding-right:10">Manage Plan</span>
<p></p>
<div style="line-height: 2;">Insure your account is tied to a cloud service provider.
<br>We support <span class="bold">google-drive, dropbox, one-drive or box. </span>
</div>
<p>
<div class="bold active-button border-round" style="width:50%" onclick="jx.modal.show({url:'https://healthcareio.the-phi.com/store/healthcareio/plans'})">
<div>
<img src="{{context}}/static/img/logo.svg" />
</div>
<div align="center">Open Plan Console</div>
</div>
</p>
</div>
<br>
<div class="border-right" style="height:30%"></div>
</div>
<div class="_border-right"></div>
<div >
<span class="caption bold border-bottom" style="padding-right:10">
Manage Processes</span>
<p>
<div class="input-form" style="grid-template-columns: 30% auto;">
<div class="item" style="grid-row:1; grid-column:1; ">
<div class="label">Process #</div>
<input type="text" class="procs batch"placeholder="#" style="width:64px; text-align:right" value="{{args.batch}}" onchange="healthcare.io.apply()"/>
</div>
<div class="item" style="grid-row:1; grid-column:2 ">
<div class="label">Folder #</div>
<input type="text" placeholder="Process counts" value="/data"/ class="data folder" disabled>
</div>
</div>
<div style="display:grid; grid-template-columns:repeat(2,215px); gap:2px;">
<div class="active-button border-round bold io-apply" style="margin-top:32; display:none" onclick="healthcare.io.apply()">
<div class="icon"><i class="far fa-save" style="font-size:28; color:#4682B4"></i></div>
<div align="center">Apply</div>
</div>
<div class="active-button border-round bold" style="margin-top:32" onclick="healthcare.io.stop()">
<i class="far fa-stop-circle" style="font-size:28; color:maroon"></i>
<div align="center">Stop</div>
</div>
<div class="active-button border-round bold" style="margin-top:32" onclick="healthcare.io.run()">
<i class="fas fa-running" style="font-size:28; color:green"></i>
<div align="center">Run</div>
</div>
</div>
</p>
<p>
<div class="code">
<div class="bold"># The command that will be executed</div>
<div>healthcare-io.py --parse --folder /data --batch <span class="batch">{{args.batch}}</span></div>
</div>
</p>
<p>
<div style="display:grid; grid-template-columns:auto 48px ; gap:2px">
<div class="bold caption border-bottom">Process Monitoring</div>
<div class="active" align="center" title="reload" onclick="monitor.data()"><i class="fas fa-sync"></i></div>
</div>
<div class="small">Powered by smart-top</div>
<p></p>
<div class="tabs">
<div class="tab selected" onclick="select(this)">
<div class="active" data-value="process" >
<i class="far fa-clock" style="color:maroon"></i>
<span>Process</span>
</div>
</div>
<div class="tab" onclick="select(this)">
<div class="active" data-value="files"><i class="fas fa-file-alt"></i> Files</div>
</div>
<div class="tab" onclick="select(this)">
<div class="active" data-value="export"><i class="fas fa-upload"></i> Export</div>
</div>
</div>
<div class="data-info">
<div class="process ">
<div class="board"></div>
<div class="small" align="center">
<div class="border-top bold" style="color:#4682B4;">Running Processes and resource usage</div>
</div>
</div>
<div class="files">
<div class="board"></div>
<div class="small" align="center">
<div class="border-top bold" style="color:#4682B4;">Summary of files found and processed</div>
</div>
</div>
<div class="export">
<p></p>
<div class="etl">
<div class="" >
<div class="menu" style="position:absolute; width:200">
<div class="items ">
<div class="bold active" style="display:grid; grid-template-columns:80% auto;">
<span>
<i class="fas fa-cloud"></i>
Cloud</span>
<span class="glyph">
<i class="fas fa-angle-down"></i>
</span>
</div>
<div class="item-group border-round border small">
<div class="item" onclick="healthcare.io.publish.database.init('s3')">AWS S3</div>
<div class="item" onclick="healthcare.io.publish.database.init('bigquery')">Google Bigquery</div>
</div>
</div>
<div class="items ">
<div class="bold active"style="display:grid; grid-template-columns:80% auto;">
<span>
<i class="fas fa-database"></i>
Database</span>
<span class="glyph">
<i class="fas fa-angle-down"></i>
</span>
</div>
<div class="item-group border-round border small">
<div class="bold">SQL</div>
<div class="item" style="margin-left:15px; margin-right:32px" onclick="healthcare.io.publish.database.init('postgresql')">PostgreSQL</div>
<div class="item" style="margin-left:15px; margin-right:32px" onclick="healthcare.io.publish.database.init('mysql')">MySQL</div>
<div class="bold">NoSQL</div>
<div class="item" style="margin-left:15px; margin-right:32px" onclick="healthcare.io.publish.database.init('mongodb')">Mongodb</div>
<div class="item" style="margin-left:15px; margin-right:32px" onclick="healthcare.io.publish.database.init('couchdb')">Couchdb</div>
</div>
</div>
</div>
</div>
<div>
<div class="active-button border-round" style="width:50%">
<div class="icon"><i class="fas fa-running" style="font-size:28"></i></div> <div class="bold" align="center">Start</div>
</div>
</div>
</div>
</div>
</div>
</p>
</div>
</div>

View File

@ -0,0 +1,78 @@
<link href="{{context}}/static/css/fa/css/all.css" type="text/css" rel="stylesheet">
<link rel="stylesheet" href="{{context}}/static/css/default.css" type="text/css">
<link href="{{context}}/static/css/borders.css" type="text/css" rel="stylesheet">
<style>
.form , input{font-family:sans-serif; font-size:18px}
.form .small {font-size:14px; line-height:2}
.mongo, .couchdb{
display:grid;
gap:2px;
}
.grid-full {display:grid; grid-template-columns: 100%;}
.grid-split-half {display:grid; grid-template-columns: 50% 50%; gap:2px;}
.store .title-bar {display:grid; align-items:center; grid-template-columns: auto 32px; padding:8px;}
.file {display:grid; align-items:center; grid-template-columns: 40% auto; gap:2px; font-family:sans-serif; padding:8px}
.file input {display:none}
.file label {padding:8px;}
</style>
<div class="store">
<div class="title-bar">
<div class="caption">Export Module <span class="bold id"></span></div>
<div class="active" align="center" onclick="jx.modal.close()">
<i class="fas fa-times"></i>
</div>
</div>
<p></p>
<div class="cloud form border-round">
<div class="small border-round">
Please provide select access-key file or service account key file to perform ETL
to <span class="bold id"></span>. <br>The files will be re-created in JSON format
</div>
<div class="file">
<label class="active-button border-round">
<span style="font-family:sans-serif">
<i class="icon fas fa-file-upload" style="font-size:24px"></i>
</span>
<div>Select key file</div>
<input type="file" id="file" aria-label="File browser example" onchange="publish.set.file()">
</label>
<div class="name small black bold" style="padding-left:24px"></div>
</div>
</div>
<div class="database form border-round">
<div class="small border-round">
Tables / collections will be automatically inferred in the <span class="bold id"></span>
</div>
<div class="mongo">
<div class="grid-split-half">
<input type="text" class="host" placeholder="host:port"/>
<input type="text" class="host" placeholder="database"/>
</div>
<div class="grid-split-half">
<input type="text" placeholder="user"/>
<input type="text" placeholder="password"/>
</div>
</div>
<p></p>
<div>
<br>
<div class="active-button border-round" style="margin-left:30%; margin-right:30%">
<div class="icon">
<i class="fas fa-check"></i>
</div>
<div class="bold" align="center">Export Now</div>
</div>
</div>
</div>
</div>

View File

@ -24,6 +24,7 @@ import sys
from itertools import islice
from multiprocessing import Process
import transport
import jsonmerge
class void :
pass
class Formatters :
@ -49,8 +50,9 @@ class Formatters :
"""
This function is designed to split an x12 row and
"""
value = []
if row.startswith(prefix) is False:
value = []
for row_value in row.replace('~','').split(sep) :
@ -65,10 +67,12 @@ class Formatters :
else :
value.append(row_value.replace('\n',''))
return [xchar.replace('\r','') for xchar in value] #row.replace('~','').split(sep)
value = [xchar.replace('\r','') for xchar in value] #row.replace('~','').split(sep)
else:
return [ [prefix]+ self.split(item,'>') for item in row.replace('~','').split(sep)[1:] ]
value = [ [prefix]+ self.split(item,'>') for item in row.replace('~','').split(sep)[1:] ]
return value if type(value) == list and type(value[0]) != list else value[0]
def get_config(self,config,row):
"""
This function will return the meaningfull parts of the configuration for a given item
@ -92,7 +96,6 @@ class Formatters :
if _row[0] in config['SIMILAR'] :
key = config['SIMILAR'][_row[0]]
_info = config[key]
return _info
def hash(self,value):
@ -130,7 +133,7 @@ class Formatters :
terms = value[1].split('>')
return {'type':terms[0],'code':terms[1],"amount":float(value[2])}
else:
return {"code":value[2],"type":value[1],"amount":float(value[3])}
def sv2(self,value):
#
@ -170,27 +173,56 @@ class Formatters :
def pos(self,value):
"""
formatting place of service information within a segment (REF)
@TODO: In order to accomodate the other elements they need to be specified in the configuration
Otherwise it causes problems on export
"""
xchar = '>' if '>' in value else ':'
x = value.split(xchar)
x = {"code":x[0],"indicator":x[1],"frequency":x[2]} if len(x) == 3 else {"code":x[0],"indicator":None,"frequency":None}
return x
return x['code']
class Parser (Process):
def __init__(self,path):
"""
:path path of the configuration file (it can be absolute)
"""
Process.__init__(self)
self.utils = Formatters()
self.get = void()
self.get.value = self.get_map
self.get.default_value = self.get_default_value
_config = json.loads(open(path).read())
self._custom_config = self.get_custom(path)
self.config = _config['parser']
self.store = _config['store']
self.files = []
self.set = void()
self.set.files = self.set_files
self.emit = void()
self.emit.pre = None
self.emit.post = None
def get_custom(self,path) :
"""
:path path of the configuration file (it can be absolute)
"""
#
#
_path = path.replace('config.json','')
if _path.endswith(os.sep) :
_path = _path[:-1]
_config = {}
_path = os.sep.join([_path,'custom'])
if os.path.exists(_path) :
files = os.listdir(_path)
if files :
fullname = os.sep.join([_path,files[0]])
_config = json.loads ( (open(fullname)).read() )
return _config
def set_files(self,files):
self.files = files
def get_map(self,row,config,version=None):
@ -241,15 +273,18 @@ class Parser (Process):
value = {key:value} if key not in value else value
else:
if 'syn' in config and value in config['syn'] :
value = config['syn'][value]
if type(value) == dict :
object_value = dict(object_value, **value)
else:
object_value[key] = value
else:
#
# we are dealing with a complex object
@ -269,25 +304,35 @@ class Parser (Process):
return object_value
def apply(self,content,_code) :
"""
:file content i.e a segment with the envelope
:_code 837 or 835 (helps get the appropriate configuration)
:content content of a file i.e a segment with the envelope
:_code 837 or 835 (helps get the appropriate configuration)
"""
util = Formatters()
# header = default_value.copy()
value = {}
for row in content[:] :
row = util.split(row.replace('\n','').replace('~',''))
_info = util.get.config(self.config[_code][0],row)
if self._custom_config and _code in self._custom_config:
_cinfo = util.get.config(self._custom_config[_code],row)
else:
_cinfo = {}
# _info = self.consolidate(row=row,type=_code,config=_info,util=util)
# print ([row[0],_info])
# print ()
# continue
# _cinfo = util.get.config(self._custom_config[_code],row)
if _info :
try:
_info = jsonmerge.merge(_info,_cinfo)
tmp = self.get.value(row,_info)
# if 'P1080351470' in content[0] and 'PLB' in row:
# print (_info)
# print (row)
# print (tmp)
if not tmp :
continue
if 'label' in _info :
@ -300,10 +345,10 @@ class Parser (Process):
else:
if label not in value:
value[label] = [tmp]
elif len(list(tmp.keys())) == 1 :
# print "\t",len(claim[label]),tmp
index = len(value[label]) -1
value[label][index] = dict(value[label][index],**tmp)
# elif len(list(tmp.keys())) == 1 :
# # print "\t",len(claim[label]),tmp
# index = len(value[label]) -1
# value[label][index] = dict(value[label][index],**tmp)
else:
value[label].append(tmp)
tmp['_index'] = len(value[label]) -1
@ -319,7 +364,9 @@ class Parser (Process):
elif 'field' in _info :
name = _info['field']
value[name] = tmp
# value[name] = tmp
value = jsonmerge.merge(value,{name:tmp})
else:
@ -327,13 +374,14 @@ class Parser (Process):
pass
except Exception as e :
print ('__',e.args)
pass
return value if value else {}
def get_default_value(self,content,_code):
util = Formatters()
TOP_ROW = content[1].split('*')
CATEGORY= content[2].split('*')[1].strip()
@ -352,6 +400,8 @@ class Parser (Process):
value['payer_id'] = SENDER_ID
else:
value['provider_id'] = SENDER_ID
#
# Let's parse this for default values
return value
def read(self,filename) :
@ -374,8 +424,14 @@ class Parser (Process):
INITIAL_ROWS = file[:4]
if len(INITIAL_ROWS) < 3 :
return None,[{"name":filename,"completed":False}],None
section = 'HL' if INITIAL_ROWS[1].split('*')[1] == 'HC' else 'CLP'
_code = '837' if section == 'HL' else '835'
# section = 'HL' if INITIAL_ROWS[1].split('*')[1] == 'HC' else 'CLP'
# _code = '837' if section == 'HL' else '835'
# print ([_code,section])
_code = INITIAL_ROWS[2].split('*')[1].strip()
# section = 'CLP' if _code == '835' else 'HL'
section = self.config[_code][0]['SECTION'].strip()
#
# adjusting the
DEFAULT_VALUE = self.get.default_value(INITIAL_ROWS,_code)
DEFAULT_VALUE['name'] = filename.strip()
#
@ -383,22 +439,30 @@ class Parser (Process):
# index 1 identifies file type i.e CLM for claim and CLP for remittance
segment = []
index = 0;
_toprows = []
for row in file :
row = row.replace('\r','')
if not segment and not row.startswith(section):
_toprows += [row]
if row.startswith(section) and not segment:
segment = [row]
continue
elif segment and not row.startswith(section):
segment.append(row)
if len(segment) > 1 and row.startswith(section):
#
# process the segment somewhere (create a thread maybe?)
#
# default_claim = dict({"index":index},**DEFAULT_VALUE)
# print (_toprows)
_claim = self.apply(segment,_code)
# if _claim['claim_id'] == 'P1080351470' :
# print (_claim)
# _claim = dict(DEFAULT_VALUE,**_claim)
@ -418,12 +482,14 @@ class Parser (Process):
claim = self.apply(segment,_code)
if claim :
claim['index'] = len(claims)
claim = jsonmerge.merge(claim,self.apply(_toprows,_code))
claims.append(dict(DEFAULT_VALUE,**claim))
if type(file) != list :
file.close()
# x12_file = open(filename.strip(),errors='ignore').read().split('\n')
except Exception as e:
logs.append ({"parse":_code,"completed":False,"name":filename,"msg":e.args[0]})
return [],logs,None
@ -432,6 +498,9 @@ class Parser (Process):
# self.finish(claims,logs,_code)
return claims,logs,_code
def run(self):
if self.emit.pre :
self.emit.pre()
for filename in self.files :
content,logs,_code = self.read(filename)
self.finish(content,logs,_code)
@ -441,14 +510,22 @@ class Parser (Process):
if args['type'] == 'mongo.MongoWriter' :
args['args']['doc'] = 'claims' if _code == '837' else 'remits'
_args['args']['doc'] = 'logs'
else:
args['args']['table'] = 'claims' if _code == '837' else 'remits'
_args['args']['table'] = 'logs'
if content :
writer = transport.factory.instance(**args)
writer.write(content)
writer.close()
if logs :
logger = transport.factory.instance(**_args)
logger.write(logs)
logger.close()
if self.emit.post :
self.emit.post(content,logs)

View File

@ -8,14 +8,15 @@ import sys
def read(fname):
return open(os.path.join(os.path.dirname(__file__), fname)).read()
args = {
"name":"healthcareio","version":"1.3.7",
"name":"healthcareio","version":"1.4.8",
"author":"Vanderbilt University Medical Center",
"author_email":"steve.l.nyemba@vumc.org",
"include_package_data":True,
"license":"MIT",
"packages":find_packages(),
"keywords":["healthcare","edi","x12","analytics","835","837","data","transport","protocol"]
}
args["install_requires"] = ['seaborn','jinja2', 'weasyprint','data-transport@git+https://dev.the-phi.com/git/steve/data-transport.git','pymongo','numpy','cloudant','pika','boto','flask-session','smart_open']
args["install_requires"] = ['flask-socketio','seaborn','jinja2','jsonmerge', 'weasyprint','data-transport@git+https://healthcareio.the-phi.com/git/code/transport.git','pymongo','numpy','cloudant','pika','boto','botocore','flask-session','smart_open','smart-top@git+https://healthcareio.the-phi.com/git/code/smart-top.git@data-collector']
args['url'] = 'https://hiplab.mc.vanderbilt.edu'
args['scripts']= ['healthcareio/healthcare-io.py']
# args['entry_points'] = {