TMGSEQL1 ;TMG/kst/Interface with SequelSystems PMS ;03/25/06 ;;1.0;TMG-LIB;**1**;01/09/06 ;"TMG SEQUEL IMPORT FUNCTIONS ;"Kevin Toppenberg MD ;"GNU General Public License (GPL) applies ;"1-9-2006 ;"======================================================================= ;" API -- Public Functions. ;"======================================================================= ;"ASKIMPORT ;"RUNNOW provide an entry point for running import NOW. This will delete prior alerts ;"AUTOIN ;"entry point for scheduled task ;"QUIETIN ;"$$IMPORTFILE(FilePath,FileName,F2Name,ErrArray,ChgLog,PrgCallback,F2Path,DelFiles,UserID) ;"$$IMPORTGLOBAL(GRef,G2Ref,ErrArray,ChgLog,PrgCallback,UserID) ;"======================================================================= ;"PRIVATE API FUNCTIONS ;"======================================================================= ;"$$ProcessPt(OneLine,ErrArray,ChgLog,SSNArray,DUZ) ;"$$ParseLine(OneLine,Array,SSNArray) ;"UpdateDB(PtInfo,AutoRegister,ErrArray,ChgLog) ;"$$InactivePt(PMSAcctNum,SSNArray) ;"$$InvalidProvider(SequelProvider) ;"$$InvalPtName(FName,LName) ;"======================================================================= ;"DEPENDENCIES ;"TMGIOUTL ;"TMGMISC ;"======================================================================= ;"======================================================================= ;"======================================================================= ;" Below are three custom files that are used by the TMGSEQL* code ;"======================================================================= ;"File: 22706 TMG DEMOGRAPHICS IMPORT ERRORS Branch: 1 ;"REF NODE;PIECE FLD NUM FIELD NAME ;"=============================================================================== ;" 1 0;1 .01 ACCOUNT NUMBER [RNJ9,0] ;" 2 4;1 .02 CREATION DATE [D] ;" 3 4;2 .03 PATIENT NAME [F] ;" 4 0;2 1 MESSAGE [F] ;" 2;0 2 IMPORT DATA <-WP [22706.02] ;" 5 -0;1 .01 -IMPORT DATA [W] ;" 3;0 3 DIERR MESSAGE <-WP [22706.03] ;" 6 -0;1 .01 -DIERR MESSAGE [W] ;" 7 4;3 4 ALERT IEN [NJ9,0] ;" <> <> <> ;" A.) FILE NAME:------------- TMG DEMOGRAPHICS IMPORT ERRORS ;" F.) FILE ACCESS: ;" B.) FILE NUMBER:----------- 22706 DD______ @ ;" Read____ @ ;" C.) NUM OF FLDS:----------- 9 Write___ @ ;" Delete__ @ ;" D.) DATA GLOBAL:----------- ^TMG(22706, Laygo___ @ ;" ;" E.) TOTAL GLOBAL ENTRIES:-- 76 G.) PRINTING STATUS:-- Off ;"================================================================================ ;"File: 22707 TMG NAME SEX Branch: 1 ;"REF NODE;PIECE FLD NUM FIELD NAME ;"=============================================================================== ;" 1 0;1 .01 FIRST NAME [RF] ;" 2 0;2 1 SEX [S] ;"<> <> <> ;" A.) FILE NAME:------------- TMG NAME SEX ;" F.) FILE ACCESS: ;" B.) FILE NUMBER:----------- 22707 DD______ @ ;" Read____ @ ;" C.) NUM OF FLDS:----------- 2 Write___ @ ;" Delete__ @ ;" D.) DATA GLOBAL:----------- ^TMG(22707, Laygo___ @ ;" ;" E.) TOTAL GLOBAL ENTRIES:-- 698 G.) PRINTING STATUS:-- Off ;"================================================================================ ;"File: 22711 TMG UPLOAD SETTINGS Branch: 1 ;"REF NODE;PIECE FLD NUM FIELD NAME ;"=============================================================================== ;" 1 0;1 .01 NAME [RFX] ;" 2 0;2 1 DEBUG SHOW [NJ1,0X] ;" 3 1;1 1.1 DEBUG OUTPUT FILE [F] ;" 4 2;1 1.15 DEBUG OUTPUT PATH [F] ;" 5 1;2 1.2 DEBUG CUMULATIVE [NJ1,0] ;" 6 3;1 2 IMPORT DATAFILE NAME [F] ;" 7 5;1 2.1 IMPORT DATAFILE 2 NAME [F] ;" 8 4;1 2.5 IMPORT DATAFILE PATH [F] ;" 9 6;1 3 ALERT RECIPIENT <-Pntr [P200'] ;" 10 6;2 4 LAST IMPORT DATE [D] ;" 11 6;3 5 DELETE DATAFILE AFTER IMPORT? [S] ;" 12 6;4 6 PICK GENDER FROM NAME? [S] ;" 13 6;5 7 IMPORT FREQUENCY (IN HOURS) [NJ4,0] ;" <> <> <> ;" A.) FILE NAME:------------- TMG UPLOAD SETTINGS ;" F.) FILE ACCESS: ;" B.) FILE NUMBER:----------- 22711 DD______ @ ;" Read____ @ ;" C.) NUM OF FLDS:----------- 12 Write___ @ ;" Delete__ @ ;" D.) DATA GLOBAL:----------- ^TMG(22711, Laygo___ @ ;" ;" E.) TOTAL GLOBAL ENTRIES:-- 1 G.) PRINTING STATUS:-- Off ;"================================================================================ ASKIMPORT ;"Purpose: To ask user for filename and then import data. ;"Input: None ;"Output: Database is updated with data from file. ;"Result: None new DiscardName new DefPath set DefPath="/tmp/" new DefFName set DefFName="demographics.csv" new DefF2Name set DefF2Name="demographics2.csv" new FPath,FName,F2Name new ErrArray,ChLog new result new PrgsFn set PrgsFn="do ProgressBar^TMGUSRIF(TMGCUR,""Progress"",1,TMGMAX,,TMGSTART)" set PrgsFn=PrgsFn_" read *TMGkeyin:0 set:(TMGkeyin=27) TMGABORT=1" set DiscardName=$$GetFName^TMGIOUTL("Please enter file to import.",.DefPath,.DefFName,,.FPath,.FName) if DiscardName="" goto AIDone set DiscardName=$$GetFName^TMGIOUTL("Please enter 2nd file to import.",.DefPath,.DefF2Name,,.FPath,.F2Name) if DiscardName="" goto AIDone set result=$$IMPORTFILE(FPath,FName,F2Name,.ErrArray,.ChLog,PrgsFn) AIDone quit RUNNOW ;"Purpose: To provide an entry point for running import NOW. This will delete prior alerts ;"Input: none. Settings stored in File 22711 are used ;"Output: None. Progress shown to console. The database should be updated ;"Results: none write !!,"Import Sequel Demographics Now...",! new FName,F2Name,FPath new result new ErrArray,ChLog new DelFiles new UserID set FName=$$GET1^DIQ(22711,"1,","IMPORT DATAFILE NAME") set F2Name=$$GET1^DIQ(22711,"1,","IMPORT DATAFILE 2 NAME") set FPath=$$GET1^DIQ(22711,"1,","IMPORT DATAFILE PATH") set DelFiles=+$$GET1^DIQ(22711,"1,","DELETE DATAFILE AFTER IMPORT?","I") set UserID=$$GET1^DIQ(22711,"1,","ALERT RECIPIENT","I") new PrgsFn set PrgsFn="do ProgressBar^TMGUSRIF(TMGCUR,""Progress"",1,TMGMAX,,TMGSTART)" set PrgsFn=PrgsFn_" read *TMGkeyin:0 set:(TMGkeyin=27) TMGABORT=1" set result=$$IMPORTFILE(FPath,FName,F2Name,,,PrgsFn,,DelFiles,UserID) quit AUTOIN ;"Purpose: To provide an entry point for a scheduled task. This will delete prior alerts ;"Input: none. Settings stored in File 22711 are used ;"Output: None. There should be no console output. The database should be updated ;"Results: none new InitTime set InitTime=$H new UserID set UserID=$$GET1^DIQ(22711,"1,","ALERT RECIPIENT","I") do ;"clear out 'next run task number' . new TMGFDA,TMGMSG . set TMGFDA(22711,"1,",8)="@" ;"#4 = TASK FOR NEXT RUN . do FILE^DIE("E","TMGFDA","TMGMSG") ;" note: ignores TMGMSG or errors. new temp set temp=$$QuietClear^TMGSEQL3(UserID) ;"clear prior alerts & errors do QUIETIN ;" do import ;"Here I schedule the next task to run again. new HrInterval set HrInterval=$$GET1^DIQ(22711,"1,","IMPORT FREQUENCY (IN HOURS)","I") if +HrInterval>0 do . new time set time=$$HADD^XLFDT(InitTime,0,HrInterval,0) . new task set task=$$Schedule^TMGSEQL3(time,"AUTOIN^TMGSEQL1","Import of demographic data from Sequel billing system.") . ;"store 'next run task number' . set TMGFDA(22711,"1,",8)="`"_task ;"#4 = TASK FOR NEXT RUN . do FILE^DIE("E","TMGFDA","TMGMSG") ;" note: ignores TMGMSG or errors. quit QUIETIN ;"Purpose: To import data based on settings, with no user interaction (in or out) ;"Input: none. Settings stored in File 22711 are used ;"Output: None. There should be no console output. The database should be updated ;"Results: none new FName,F2Name,FPath new result new ErrArray,ChLog new DelFiles new UserID set FName=$$GET1^DIQ(22711,"1,","IMPORT DATAFILE NAME") set F2Name=$$GET1^DIQ(22711,"1,","IMPORT DATAFILE 2 NAME") set FPath=$$GET1^DIQ(22711,"1,","IMPORT DATAFILE PATH") set DelFiles=+$$GET1^DIQ(22711,"1,","DELETE DATAFILE AFTER IMPORT?","I") set UserID=$$GET1^DIQ(22711,"1,","ALERT RECIPIENT","I") set result=$$IMPORTFILE(FPath,FName,F2Name,,,,,DelFiles,UserID) quit IMPORTFILE(FilePath,FileName,F2Name,ErrArray,ChgLog,PrgCallback,F2Path,DelFiles,UserID) ;"Purpose: To import data from file specified. ;"Input: FilePath: Path of file to input. ;" FileName: The Name of file of file to input. ;" Note: This is written to import a specific file ;" created by SequelMed Systems, filled with ;" patient demographics, in CVS format ;" Note: This file will be DELETED if DelFiles=1 ;" F2Name : the name of the second demographics file in input ;" The reason for 2 files is because Sequel doesn't report the SSN in the ;" primary demographics report. So a second report must be used, and these ;" two files are merged to provide complete patient demographics. ;" Note: This file will be DELETED if DelFiles=1 ;" ErrArray: PASS BY REFERENCE. Array to receive failed data lines. ;" ChgLog: PASS BY REFERENCE. An array to receive record of changes made to database ;" PrgCallback: OPTIONAL -- if supplied, then M code contained in this string ;" will be xecuted periodically, to allow display of a progress bar etc. ;" Note: the following variables with global scope will be declared and ;" available for use: TMGCUR (current count), TMGMAX (max count), ;" TMGSTART (the start time ;" External function can signal a request an abort by setting TMGABORT=1 ;" F2Path: OPTIONAL -- path of 2nd demographics file. Default=FilePath ;" DelFiles: OPTIONAL -- if 1, then source files (FileName and F2Name) are deleted after import ;" UserID : OPTIONAL -- user to receive alerts regarding errors. Default is current user (DUZ) ;"Note: I have learned that SequelMed billing system exports ALL patients in the primary ;" export file, including one that have been marked inactive do to invalid data etc. ;" Thus, while the second file (F2Name) has limited info, it contains the list of ;" ACTIVE patients. So if a name is not included in the 2nd file, then its info will ;" be ignored in the 1st file. ;"Output: Database is updated with data from file. ;"Result: 1 successful completion, 0=error new GRef,GRef1 new G2Ref,G2Ref1 new result set F2Path=$get(F2Path,FilePath) set GRef=$name(^TMP("TMG","SEQUELIMPORT","DATA",1,$J)) ;"I use this to process array set GRef1=$name(@GRef@(1)) ;"I use this to load file kill @GRef set result=$$FTG^%ZISH(FilePath,FileName,GRef1,6) ;"load file into a global if result=0 goto IFDONE set G2Ref=$name(^TMP("TMG","SEQUELIMPORT","DATA",2,$J)) ;"I use this to process array set G2Ref1=$name(@G2Ref@(1)) ;"I use this to load file kill @G2Ref set result=$$FTG^%ZISH(F2Path,F2Name,G2Ref1,6) ;"load file into a global if result=0 goto IFDONE set UserID=$get(UserID,+$get(DUZ)) set result=$$IMPORTGLOBAL(GRef,G2Ref,.ErrArray,.ChLog,.PrgCallback,UserID) ;"Note: @GRef, @G2Ref killed at end of $$IMPORTGLOBAL() do ;"record the current time as the time of last import . do NOW^%DTC . new TMGFDA,TMGMSG . set TMGFDA(22711,"1,",4)=% ;"#4 = LAST IMPORT DATE . do FILE^DIE("E","TMGFDA","TMGMSG") ;" note: ignores TMGMSG or errors. if $get(DelFiles)=1 do . ;"Notice: After I implemented this, I realized that I have a permissions problem . ;" at my site... the uploaded files belong to the uploaded user, and deletion by . ;" this user is being blocked. I'll leave in for now... . new temp . set temp=$$DelFile^TMGIOUTL(FilePath_FileName) . set temp=$$DelFile^TMGIOUTL(F2Path_F2Name) IFDONE quit result IMPORTGLOBAL(GRef,G2Ref,ErrArray,ChLog,PrgCallback,UserID) ;"Purpose: To import data from global specified. ;"Input: GRef -- the NAME of array holding the data to import (1st file) ;" Format: @GRef@(1)=OneLine ;" @GRef@(2)=OneLine .. etc. ;" Note: This is written to import a specific file ;" created by SequelMed Systems, filled with ;" patient demographics, in CVS format ;" Note: Array will be KILLED at the end of this function. ;" G2Ref -- the NAME of array holding the data to import (2nd file) ;" Note: Array will be KILLED at the end of this function. ;" ErrArray: PASS BY REFERENCE. Array to receive failed data lines. ;" ChgLog: PASS BY REFERENCE. An array to receive record of changes made to database ;" PrgCallback: OPTIONAL -- if supplied, then M code contained in this string ;" will be xecuted periodically, to allow display of a progress bar etc. ;" Note: the following variables with global scope will be declared and ;" available for use: TMGCUR (current count), TMGMAX (max count), ;" TMGSTART (the start time ;" External function can signal a request an abort by setting TMGABORT=1 ;" UserID : OPTIONAL -- user to receive alerts regarding errors. Default is current user (DUZ) ;"Output: Database is updated with data from file. ;"Result: 1 successful completion, 0=error new TMGInvalid ;"Will be used as a globally-scoped variable in the module new result set result=1 new delay set delay=0 new TMGCUR,TMGMAX,TMGSTART,TMGABORT ;"avail for PrgCallback function set TMGABORT=0 set TMGMAX=+$order(@GRef@(""),-1) set TMGSTART=$H ;"store starting time. set UserID=$get(UserID,+$get(DUZ)) new SSNArray do XtractSSNum(G2Ref,.SSNArray) set TMGCUR=$order(@GRef@("")) if TMGCUR'="" for do quit:(TMGCUR="")!(TMGABORT=1) . new OneLine . set OneLine=$get(@GRef@(TMGCUR)) . set result=$$ProcessPt(OneLine,.ErrArray,.ChgLog,.SSNArray,UserID) . set delay=delay+1 . if (delay>30),$get(PrgCallback)'="" do ;"update progress bar every 30 cycles . . new $etrap set $etrap="write ""(Invalid M Code!. Error Trapped.)"" set $etrap="""",$ecode=""""" . . xecute PrgCallback ;"call the specified progress code. . . set delay=0 . set TMGCUR=$order(@GRef@(TMGCUR)) kill @GRef kill @G2Ref quit result ProcessPt(OneLine,ErrArray,ChgLog,SSNArray,DUZ,InputFn) ;"Purpose: To process one line from patient demographics file. ;"Input: OneLine-- One line from CVS demographics file. ;" Format is as follows, *** all on one line (comma delimited) ;" 01- patient_seq_num, ;" 02- facility_short_name, ;" 03- pat_last_name, ;" 04- pat_first_name, ;" 05- pat_account_num, ;" 06- pat_address, ;" 07- state, ;" 08- resp_last_name, ;" 09- resp_first_name, ;" 10- facility_seq_num, ;" 11- register_date, ;" 12- location_name, ;" 13- city, ;" 14- provider_short_name, ;" 15- zipcode, ;" 16- class_name, ;" 17- pat_dob, ;" 18- ref_prov_short_name, ;" 19- pat_tel_num, ;" 20- last_visit_days, ;" 21- name, ;" 22- description ;" ADDENDUM: ;" sometimes SEX will be appended to line. Format: ;" previous data^MALE or previous data^FEMALE ;" sometimes SSN will be appended to line. Format: ;" previous data^(sex)^SSNUM ;" ErrArray: PASS BY REFERENCE. Array to receive failed data lines. ;" ChgLog: PASS BY REFERENCE. An array to receive record of changes made to database ;" SSNArray: OPTIONAL -- PASS BY REFERENCE. An array with social security numbers, ;" as created by XtractSSNum() ;" DUZ: The user who will recieve alerts of errors ;" InputFn: OPTIONAL-- the name of a function to turn parse on csv line ;" default value is "ParseLine" ;" e.g. "MyFn" or "MyFn^MyRoutine". Must take same params as ParseLine ;" This will allow this code to be used on a variety of .csv files, with ;" different data-formats--each one with its own parser funtion. ;"Output: Data is put into database, if it is not there already. ;"Result: 1=OK To continue; 0=abort or bad data new XFn new PtInfo,OneErrArray new result set result=1 new AutoRegister set AutoRegister=1 set InputFn=$get(InputFn,"ParseLine") set XFn="set result=$$"_InputFn_"(.OneLine,.PtInfo,.SSNArray)" xecute XFn ;"old -- set result=$$ParseLine(.OneLine,.PtInfo,.SSNArray) if result'>0 goto PPtDone if $get(PtInfo("FACILITY"))="SAMPLE" goto PPtDone if $$UpdateDB(.PtInfo,AutoRegister,.OneErrArray,.ChgLog)=0 do . new count set count=+$get(ErrArray)+1 . set ErrArray=count . set ErrArray(count)=OneLine . merge ErrArray(count,"INFO")=OneErrArray . ;"------ . do AlertError^TMGSEQL2(OneLine,.PtInfo,.OneErrArray,DUZ) PPtDone quit result ParseLine(OneLine,Array,SSNArray) ;"Purpose: To process one line from patient demographics file. ;" Also gets data into an acceptible format. ;"Input: OneLine -- One line from CVS demographics file. (Format as per ProcessPt) ;" NOTE: if PASSED BY REFERENCE, then line may be altered such that SSN is ;" added as a 3rd piece, using ^ as a delimiter. (2nd piece used elsewhere ;" to store sex. ;" When processing line, if SSNArray doesn't provide a SSN for patient, then ;" this 3rd piece can provide the SSN ;" Array -- PASS BY REFERENCE. And OUT parameter. Any prior data killed. ;" Note: uses TMGInvalid (globally scoped var defined in this module) ;" SSNArray: OPTIONAL -- PASS BY REFERENCE. An array with social security numbers, ;" as created by XtractSSNum() ;"Output: Array is filled with Format as follows (note not all data used): ;" Array("FACILITY"), to hold 02- facility_short_name ;" Array("LAST NAME"), to hold 03- pat_last_name, ;" Array("FIRST NAME"), to hold 04- pat_first_name, ;" Array("PMS ACCOUNT NUM"), to hold 05- pat_account_num, ;" Array("ADDRESS1"), to hold 06- pat_address, ;" Array("ADDRESS2"), to hold 06- pat_address, ;" Array("ADDRESS3"), to hold 06- pat_address, ;" Array("STATE"), to hold 07- state, ;" Array("RESP LAST NAME"), to hold 08- resp_last_name, ;" Array("RESP FIRST NAME"), to hold 09- resp_first_name, ;" Array("CITY"), to hold 13- city, ;" Array("PROVIDER"), to hold 14- provider_short_name, ;" Array("ZIP CODE"), to hold 15- zipcode, ;" Array("DOB"), to hold 17- pat_dob, ;" Array("PHONE NUM"), to hold 19- pat_tel_num, ;" Array("SEX"), to hold Patient sex, if provided. ;" Array("SSNUM")=Social security number ;" Array("FULL NAME")=FIRSTNAME LASTNAME (DOB) ;" Array("FULL NAME2")=LASTNAME,FIRSTNAME (DOB) ;" Array("FULL NAME3")=LASTNAME,FIRSTNAME ;"Result: 1=OK To continue; 0=abort or bad data; -1 skip, but don't store as error new temp new result set result=1 set OneLine=$translate($get(OneLine),"""","'") ;" convert " to ' to avoid fileman error kill Array set Array("FACILITY")=$piece(OneLine,",",2) set Array("LAST NAME")=$$Trim^TMGSTUTL($piece(OneLine,",",3)) set Array("FIRST NAME")=$$Trim^TMGSTUTL($piece(OneLine,",",4)) set Array("PMS ACCOUNT NUM")=$piece(OneLine,",",5) set Array("ADDRESS1")=$piece(OneLine,",",6) set Array("STATE")=$piece(OneLine,",",7) set Array("RESP LAST NAME")=$piece(OneLine,",",8) set Array("RESP FIRST NAME")=$piece(OneLine,",",9) set Array("CITY")=$$Trim^TMGSTUTL($piece(OneLine,",",13),"""") set Array("PROVIDER")=$piece(OneLine,",",14) set Array("ZIP CODE")=$piece(OneLine,",",15) new DOB set DOB=$piece(OneLine,",",17) set DOB=$$Trim^TMGSTUTL(DOB) set DOB=$piece(DOB," ",1) ;" '03/09/05 00:00' --> '03/09/05' set Array("DOB")=DOB set Array("PHONE NUM")=$piece(OneLine,",",19) set Array("SEX")=$piece(OneLine,"^",2) set Array("FULL NAME")=Array("FIRST NAME")_" "_Array("LAST NAME")_" ("_Array("DOB")_")" set Array("FULL NAME2")=Array("LAST NAME")_","_Array("FIRST NAME")_" ("_Array("DOB")_")" set Array("FULL NAME3")=Array("LAST NAME")_","_Array("FIRST NAME") ;"do a lookup on abreviattion for ALL states, convert to external format new DIC,X,Y set DIC=5 ;"STATE file set DIC(0)="M" set X=Array("STATE") do ^DIC set Array("STATE")=$piece(Y,"^",2) ;"convert Sequel format to VistA format if Array("PROVIDER")'="" do . set Array("PROVIDER")=$$ConvProvider(Array("PROVIDER")) if Array("PROVIDER")="SKIP" set result=0 goto PLDone ;" VistA address allows for: ;" .111 -- address line 1 ;" .112 -- address line 2 ;" .113 -- address line 3 ;" BUT, each line must be 3-35 characters ;" Sequel puts this all on one line. ;" SO, I need to divide the Sequel line if not 3-35 new value set value=Array("ADDRESS1") if $length(value)'<35 do . new s1,s2 . do NiceSplit^TMGSTUTL(value,35,.s1,.s2,3) . set Array("ADDRESS1")=s1 . if $length(s2)'<35 do . . do NiceSplit^TMGSTUTL(s1,35,.s1,.s2,3) . . set Array("ADDRESS2")=s1 ;"<-- is this correct? . . if s2'="" set Array("ADDRESS3")=$extract(s2,1,35) . else set Array("ADDRESS2")=s2 ;"Ensure proper length of city. set Array("CITY")=$extract(Array("CITY"),1,15) if $length(Array("CITY"))=1 set Array("CITY")=Array("CITY")_" " ;"Ensure proper length of phone if $length(Array("PHONE NUM"))<7 kill Array("PHONE NUM") new AcctNum set AcctNum=$get(Array("PMS ACCOUNT NUM")) new SSNum set SSNum=$get(SSNArray(AcctNum)) if SSNum=999999999 set SSNum=0 if +SSNum=0 do ;"see if 3rd ^ piece holds SSNum data . set SSNum=$piece(OneLine,"^",3) ;"note this won't overwrite valid data from SSNArray() if SSNum>0 do . set Array("SSNUM")=SSNum . set $piece(OneLine,"^",3)=SSNum if result'=0 do . if $$InvalPtName(Array("FIRST NAME"),Array("LAST NAME"))=1 set result=-1 quit . if $$InactivePt(Array("PMS ACCOUNT NUM"),.SSNArray)=1 do xx . . set result=-1 . . ;"write !,"Skipping: ",Array("FULL NAME3"),! ;"temp PLDone quit result ConvProvider(SequelProvider) ;"Purpose: To convert Sequel provider shortname to VistA file 200 name. ;"Input: SequelProvider ;"Result: VistA provider name (string), or "" if not found, or "SKIP" if not to be used new result set result="" if $$InvalidProvider(SequelProvider) set result="SKIP" goto ConPrDone if SequelProvider="SAMPLE" set result="SKIP" goto ConPrDone new TMGARRAY,TMGMSG do FIND^DIC(200,,".01",,SequelProvider,"*","TMG",,,"TMGARRAY","TMGMSG") if +TMGARRAY("DILIST",0)>0 do . set result=TMGARRAY("DILIST",1,1) else do . new DIC . set DIC=200 . ;"try converting name and doing quiet lookup (KTOPPEN->TOPPEN,K) . set X=$extract(SequelProvider,2,99)_","_$extract(SequelProvider,1) . do ^DIC . if (+Y=-1)&(1=0) do ;"<--- FEATURE TURNED OFF. If not found, don't ask (no longer needed) . . if $data(TMGInvalid(SequelProvider))'=0 quit . . write !,"Please help match the Sequel 'shortname' to a VistA provider name.",! . . write "This should have to be done only once.",! . . write "Enter ^ if the provider name is not valid.",! . . write "Please enter VistA provider name for: '",SequelProvider,"'",! . . set DIC(0)="AEQM" . . do ^DIC . . write ! . if +Y>-1 do . . new DFN set DFN=+Y . . new TMGFDA set TMGFDA(200,DFN_",",22702)=SequelProvider . . kill TMGMSG . . do FILE^DIE(,"TMGFDA","TMGMSG") ;"ignore errors . . set result=$piece(Y,"^",2) . else do . . set TMGInvalid(SequelProvider)="" ConPrDone quit result InvalPtName(FName,LName) ;"Purpose: To determine if the Patient name is invalid (i.e. CAP TOPPENBERG, or INSURANCE INSURANCE etc.) ;"Input: FName,LName -- the first and last names ;"Result: 1 if name is invalid, 0 if OK name new result set result=0 if FName="CAP" do ;"screen out 'CAP TOPPENBERG' etc ?? entries ?? . new DIC set DIC=200 . set DIC(0)="M" . set X=LName . do ^DIC . if +Y>0 set result=1 if (FName="INSURANCE")&(LName="INSURANCE") set result=1 quit result InactivePt(PMSAcctNum,SSNArray) ;"Purpose: to determine if patient is inactive, and should be skipped. ;" This is determined by testing for existence of AccountNumber in SSNArray. ;" SSNArray is created from the 2nd demographics file. This is a list of ACTIVE patients, ;" which is different from the 1st demographics file--which holds ALL patients. ;"Input: PMSAcctNum -- as stored in PtInfo("PMS ACCOUNT NUM") ;" SSNArray: PASS BY REFERENCE. An array with social security numbers, as created by XtractSSNum() ;"Result: 1 if patient is INACTIVE, and should be skipped. ;" 0 if OK to use new result set result=+$get(SSNArray(PMSAcctNum))'>0 quit result InvalidProvider(SequelProvider) ;"Purpose: To return if provider should not be used (i.e. cause data to be skipped) ;"Input: SequelProvider ;"Result: 0: OK to use provider ;" 1: Don't use provider new result set result=0 if SequelProvider="SAMPLE" set result=1 if SequelProvider="GREENEVILLE" set result=1 if SequelProvider="AFOSTER" set result=1 if SequelProvider="AFTON" set result=1 if SequelProvider="JWRIGHT" set result=1 ;"not an active provider ;"These providers are leaving group, so don't import their data. if SequelProvider="CPERRY" set result=1 if SequelProvider="OSWARNER" set result=1 if SequelProvider="SGILES" set result=1 if SequelProvider="SPENNY" set result=1 if SequelProvider="TFULLER" set result=1 quit result UpdateDB(PtInfo,AutoRegister,ErrArray,ChgLog) ;"Purpose: To put that data from the PtInfo array into the database (if needed) ;"Input: PtInfo -- array (PASS BY REFERENCE), with the following items being used: ;" PtInfo("LAST NAME"), to hold 03- pat_last_name, ;" PtInfo("FIRST NAME"), to hold 04- pat_first_name, ;" PtInfo("PMS ACCOUNT NUM") ----> field 22701 (custom field) ;" PtInfo("ADDRESS") ----> field .111 ;" PtInfo("STATE") ----> field .115 ;" PtInfo("CITY") ----> field .114 ;" PtInfo("ZIP CODE") ----> field .1112 ;" PtInfo("PHONE NUM") ----> field .131 ;" PtInfo("PROVIDER") ----> field .1041 ;" PtInfo("SSNUM") ----> field .09 ;" AutoRegister: if 1, then patient will be automatically added/registered ;" ErrArray -- PASS BY REFERENCE. And OUT parameter to get back error info. ;" ChgLog: PASS BY REFERENCE. An array to receive record of changes made to database ;"Output: Data is put into database, if it is not there already. ;"Result: 1 successful completion, 0=error new Entry new result set result=1 new Name,TMGDOB,DFN new TMGARRAY,TMGMSG new PriorErrorFound new NewInfo new IENS new index kill ErrArray new TMGDEBUG set TMGDEBUG=-1 ;"//EXTRA QUIET mode --> shut down TMGDBAPI messages ;"NOTE: I need to have some method such that IF a patient is positively matched ;" (i.e. via SSNUM or PMS Account number), THEN changes in spelling of name, or ;" DOB on Sequel side should be reflected in VistA. Currently, I don't this ;" this happens. new Fields set Fields(22701)="PMS ACCOUNT NUM" set Fields(.111)="ADDRESS1" set Fields(.112)="ADDRESS2" set Fields(.113)="ADDRESS3" set Fields(.115)="STATE" set Fields(.114)="CITY" set Fields(.1112)="ZIP CODE" set Fields(.131)="PHONE NUM" set Fields(.1041)="PROVIDER" set Fields(.02)="SEX" set Fields(.09)="SSNUM" set Fields="22701;.111;.112;.113;.115;.114;.1112;.131;.1041;.09" set Name=$get(PtInfo("LAST NAME"))_","_$get(PtInfo("FIRST NAME")) set Name=$$FormatName^TMGMISC(Name) set TMGDOB=$get(PtInfo("DOB")) set Entry(.01)=Name set Entry(.03)=TMGDOB if $get(PtInfo("SEX"))'="" set Entry(.02)=$get(PtInfo("SEX")) set Entry(.09)=$get(PtInfo("SSNUM")) set DFN=$$GetDFN(.PtInfo) if (DFN=0)&($get(AutoRegister)=1) do . set ErrArray=-1 ;"extra quiet mode. . if $get(Entry(.02))="" do ;"autopick gender if missing . . new AutoPick . . set AutoPick=$$GET1^DIQ(22711,"1,","PICK GENDER FROM NAME?","I") . . if AutoPick'=1 quit . . set Entry(.02)=$$GetSex^TMGSEQL2($get(PtInfo("FIRST NAME"))) . ;"OK, can't find, so will add new patient. . set DFN=+$$AddNewPt^TMGGDFN(.Entry,.ErrArray) . if DFN'=0 set ChLog(Name_" "_TMGDOB,0)="ADDED PATIENT: "_Name_" "_TMGDOB if DFN=0 do goto UDBDone ;"failure . set result=0 . set ErrArray(0)=$$NameError^TMGSEQL2(.ErrArray) ;"get name if DIERR encountered. . if ErrArray(0)["DOB" do . . ;"write !,"DOB error found for: ",PtInfo("FULL NAME"),! . if ErrArray(0)="" do . . set ErrArray(0)="PATIENT NOT IN DATABASE:" ;"if changed, also change in TMGSEQL2.m set IENS=DFN_"," ;"use DFN(IEN in file 2) to get data into database do GETS^DIQ(2,IENS,Fields,"","TMGARRAY","TMGMSG") ;"check for errors. if $data(TMGMSG("DIERR"))'=0 do goto UDBDone . set result=0 . merge ErrArray=TMGMSG("DIERR") . ;"do ShowDIERR^TMGDEBUG(.TMGMSG,.PriorErrorFound) kill TMGMSG ;"If any data in data base differs from Array, setup NewInfo new UpdateNeeded set UpdateNeeded=0 new abort set abort=0 set index=$order(Fields("")) for do quit:(+index'>0)!(abort=1) . new field set field=Fields(index) . if $data(PtInfo(field)),$get(TMGARRAY(2,IENS,index))'=$get(PtInfo(field)) do . . new value set value=$get(PtInfo(field)) . . if index=.1112 do . . . if +value'=0 set NewInfo(index)=value . . else if (index=.09)&(+value'=0)&(+TMGARRAY(2,IENS,index)'=0) do . . . if TMGARRAY(2,IENS,index)["P" do quit . . . . set NewInfo(index)=value . . . ;"we have CONFLICTING SOCIAL SECURITY NUMBERS --> PROBLEM... . . . set ErrArray(0)="CONFLICTING SS-NUMBERS: " ;"NOTE! if error message format is changed, also change in TMGSEQL2 . . . set ErrArray(0)=ErrArray(0)_"Sequel#="_PtInfo(field)_" vs. VistA#="_TMGARRAY(2,IENS,index) . . . set abort=1,result=0 . . else set NewInfo(index)=value . . set UpdateNeeded=1 . set index=$order(Fields(index)) if (UpdateNeeded=0)!(abort=1) goto UDBDone ;"Setup FDA array for database update new TMGFDA set index=$order(NewInfo("")) if index'="" do . for do quit:(+index'>0) . . set TMGFDA(2,IENS,index)=NewInfo(index) . . set index=$order(NewInfo(index)) . ; . do FILE^DIE("E","TMGFDA","TMGMSG") . if $data(TMGMSG("DIERR"))'=0 do ;"goto UDBDone . . set result=0 . . merge ErrArray=TMGMSG("DIERR") merge ChLog($get(Name,"?")_" "_$get(TMGDOB,"?"),1)=NewInfo UDBDone quit result GetDFN(PtInfo) ;"Purpose: Serve as interface to ^TMGGDFN functions (using PtInfo as input) ;"Input: PtInfo, Array of PtInfo, as defined in UpdateDB, and created by ParseLine ;"Result: the IEN in file 2 (i.e. DFN) if found, otherwise 0 if not found. new Entry,Name,DOB,DFN set Name=$get(PtInfo("LAST NAME"))_","_$get(PtInfo("FIRST NAME")) set Name=$$FormatName^TMGMISC(Name) set DOB=$get(PtInfo("DOB")) set Entry(.01)=Name set Entry(.03)=DOB set Entry(.02)=$get(PtInfo("SEX")) set Entry(.09)=$get(PtInfo("SSNUM")) set DFN=+$$LookupPatient^TMGGDFN(.Entry) ;"get IEN in file 2 of patient ;"do an extended search with increasing intensity. if +DFN=0 set DFN=$$ExtraLookup^TMGGDFN(.Entry,1) if +DFN=0 set DFN=$$ExtraLookup^TMGGDFN(.Entry,2) if +DFN=0 set DFN=$$ExtraLookup^TMGGDFN(.Entry,3) quit DFN XtractSSNum(G2Ref,SSNArray) ;"Purpose: To extract info from 2nd demographics file into an array of SSNums. ;"Input: G2Ref - Name of global array holding 2nd demographics file ;" Note: Format of each line is as follows: ;" scratchNum,AccountNumber,LastName,FirstName,SSNUM ... (other data is redundant) ;" i.e. SSNUM is the 5th piece ;" SSNArray -- PASS BY REFERENCE. An OUT parameter. See format below ;"Output: SSNArray will be filled as follows: ;" SSNArray(SequelAccountNumber)=SSNum ;"Result: None ;"Note: 3/2/06 modification: ;" An entry for every SequelAccountNumber will be created. If SSNum is invalid, it will ;" be converted to 0, but an entry will still be created, i.e. ;" SSNArray(SequelAccountNumber)=0 new i set i=$order(@G2Ref@("")) if i'="" for do quit:(i="") . new OneLine,AcctNum,SSNum . set OneLine=$get(@G2Ref@(i)) . set AcctNum=$piece(OneLine,",",2) . set SSNum=$$Trim^TMGSTUTL($piece(OneLine,",",5)) . new value set value=0 ;"default value . if +SSNum'<999999 do ;"force at least 6 digits --> allow 0000 11 1111 . . if $length(SSNum)'=9 do . . . set SSNArray("ERRORS",AcctNum)=SSNum ;"leaves value="" --> not used . . else do . . . ;"set SSNArray(AcctNum)=SSNum . . . set value=SSNum . set SSNArray(AcctNum)=value . set i=$order(@G2Ref@(i)) quit