TMGSEQL1B ;TMG/kst/Interface with a generic PMS ;03/25/06
          ;;1.0;TMG-LIB;**1**;01/09/06
 
 ;"TMG DEMOGRAPHICS IMPORT FUNCTIONS
 ;"Custom import routines for Clinica Adelante
 ;"Kevin Toppenberg MD
 ;"GNU General Public License (GPL) applies
 ;"6-12-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)
 ;"$$InvalPtName(FName,LName)
 ;"$$GetDFN(PtInfo)
 
 
 ;"=======================================================================
 ;"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 PMS 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 PMS 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
        ;"           *** F2Name Won't be used in this alteration of the code...
        ;"         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
        ;"           *** F2Path Won't be used in this alteration of the code...
        ;"         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","PMSIMPORT","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","PMSIMPORT","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.
        ;"              *** Note: G2Ref won't be used in this alteration of the code.
        ;"         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()
        ;"              *** Note: This won't be used by this alteration of the code.
        ;"    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.
        ;"         This parser is written to handle the dataformat as put out by the PMS
        ;"         at the Clinica Adelante, with Matthew King, MD and Benjamin Guldborg
        ;"Input: OneLine -- One line from CVS demographics file. (Format as per ProcessPt)
        ;"      Format is as follows, *** all on one line (comma delimited)
        ;"      Note: Only a few of these fields are used... cde could be modified for use later
        ;"              This would be done by putting data field into Array("SOME NAME")=value
        ;"              Then modify UpdateDB to put data into VistA
        ;"      01-PatientProfileId
        ;"      02-PatientId
        ;"      03-Inactive
        ;"      04-Prefix
        ;"      05-First
        ;"      06-Middle
        ;"      07-Last
        ;"      08-Suffix
        ;"      09-Address1
        ;"      10-Address2
        ;"      11-City
        ;"      12-State
        ;"      13-Zip
        ;"      14-Country
        ;"      15-Phone1
        ;"      16-Phone1Type
        ;"      17-Phone2
        ;"      18-Phone2Type
        ;"      19-County
        ;"      20-EMailAddress
        ;"      21-EmpStat
        ;"      22-EmpStatusDate
        ;"      23-EmpOccup
        ;"      24-EduStat
        ;"      25-SchoolName
        ;"      26-SSN
        ;"      27-Birthdate
        ;"      28-DeathDate
        ;"      29-Sex
        ;"      30-Race
        ;"      31-MaritalStat
        ;"      32-GuarantorId
        ;"      33-GarPrefix
        ;"      34-GarFirst
        ;"      35-GarMiddle
        ;"      36-GarLast
        ;"      37-GarSuffix
        ;"      38-GarAddress1
        ;"      39-GarAddress2
        ;"      40-GarCity
        ;"      41-GarState
        ;"      42-GarZip
        ;"      43-GarCountry
        ;"      44-GarPhone1
        ;"      45-GarPhoneType1
        ;"      46-GarPhone2
        ;"      47-GarPhoneType2
        ;"      48-GarEmail
        ;"      49-GarSSN
        ;"      50-GarBirthDate
        ;"      51-GarSex
        ;"      52-GarRealation
        ;"      53-FinancialClass
        ;"      54-MedicalRecordNumber
        ;"      55-PCPDoctor
        ;"      56-PCFacility
        ;"
        ;"      ---- Below is the original data fields from Sequel PMS (FYI)---
        ;"      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
 
        ;"         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")
        ;"        Array("LAST NAME")
        ;"        Array("FIRST NAME")
        ;"        Array("MIDDLE NAME") <--- NEW
        ;"        Array("NAME SUFFIX") <--- NEW
        ;"        Array("NAME PREFIX") <--- NEW
        ;"        Array("PMS ACCOUNT NUM")
        ;"        Array("ADDRESS1")
        ;"        Array("ADDRESS2")
        ;"        Array("ADDRESS3")
        ;"        Array("STATE")
        ;"        Array("RESP LAST NAME")
        ;"        Array("RESP FIRST NAME")
        ;"        Array("CITY")
        ;"        Array("PROVIDER")
        ;"        Array("ZIP CODE")
        ;"        Array("DOB")
        ;"        Array("PHONE NUM")
        ;"        Array("SEX")
        ;"        Array("SSNUM")=Social security number
        ;"        Array("FULL NAME")=FIRSTNAME MIDDLENAME LASTNAME SUFFIX(DOB)
        ;"        Array("FULL NAME2")=LASTNAME,FIRSTNAME MIDDLE SUFFIX (DOB)
        ;"        Array("FULL NAME3")=LASTNAME,FIRSTNAME MIDDLE SUFFIX
        ;"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")="ADELANTE"  ;"hard code for only 1 site
        set Array("LAST NAME")=$$Trim^TMGSTUTL($piece(OneLine,",",7))
        set Array("FIRST NAME")=$$Trim^TMGSTUTL($piece(OneLine,",",5))
        set Array("MIDDLE NAME")=$$Trim^TMGSTUTL($piece(OneLine,",",6))
 
        set Array("NAME SUFFIX")=$$Trim^TMGSTUTL($piece(OneLine,",",6))
        ;"I'm not sure what to do with prefix yet -- not used.
        set Array("NAME PREFIX")=$$Trim^TMGSTUTL($piece(OneLine,",",6))
 
        set Array("PMS ACCOUNT NUM")=$piece(OneLine,",",2)
        set Array("ADDRESS1")=$piece(OneLine,",",9)
        set Array("ADDRESS2")=$piece(OneLine,",",10)
        if Array("ADDRESS2")="Same As Above" set Array("ADDRESS2")=""
        set Array("STATE")=$piece(OneLine,",",12)
        set Array("RESP LAST NAME")=$piece(OneLine,",",36)
        set Array("RESP FIRST NAME")=$piece(OneLine,",",34)
        set Array("CITY")=$$Trim^TMGSTUTL($piece(OneLine,",",11),"""")
        set Array("PROVIDER")=""
        set Array("ZIP CODE")=$piece(OneLine,",",13)
        new DOB set DOB=$piece(OneLine,",",27)
        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,",",15)
        set Array("SEX")=$piece(OneLine,"^",29)
 
        new tMName set tMName=$get(Array("MIDDLE NAME"))
        if tMName'="" set tMName=" "_tMName  ;"add space only if middle name provided
        new tSuffix set tSuffix=$get(Array("NAME SUFFIX"))
        if tSuffix'="" set tSuffix=" "_tSuffix  ;"add space only if suffix provided
        set Array("FULL NAME")=Array("FIRST NAME")_tMName_" "_Array("LAST NAME")_tSuffix_" ("_Array("DOB")_")"
        set Array("FULL NAME2")=Array("LAST NAME")_","_Array("FIRST NAME")_tMName_tSuffix_" ("_Array("DOB")_")"
        set Array("FULL NAME3")=Array("LAST NAME")_","_Array("FIRST NAME")_tMName_tSuffix
 
        ;"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)
 
        ;"  VistA address allows for:
        ;"      .111 -- address line 1
        ;"      .112 -- address line 2
        ;"      .113 -- address line 3
        ;"      BUT, each line must be 3-35 characters
        ;"  PMS might not match this
        ;"  SO, I need to divide the line if not 3-35
        new value set value=$get(Array("ADDRESS1"))
        if $length(value)'<35 do
        . new s1,s2
        . do NiceSplit^TMGSTUTL(value,35,.s1,.s2,3)
        . set Array("ADDRESS1")=s1
        . if $get(Array("ADDRESS2"))'="" set s2=s2_"; "_$get(Array("ADDRESS2"))
        . set Array("ADDRESS2")=s2
        set value=$get(Array("ADDRESS2"))
        if $length(value)'<35 do
        . do NiceSplit^TMGSTUTL(value,35,.s1,.s2,3)
        . set Array("ADDRESS2")=s1
        . if s2'="" set Array("ADDRESS3")=$extract(s2,1,35)
 
        ;"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 SSNum set SSNum=$$Trim^TMGSTUTL($piece(OneLine,",",26))
        if +SSNum'=SSNum set SSNum=""   ;"remove alpha answers such as 'UNKNOWN'
        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
 
PLDone
        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,DFN
 
        set Entry(.01)=$$FormatName^TMGMISC($get(Array("FULL NAME3")))
        set Entry(.03)=$get(PtInfo("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
 
 
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("FULL NAME3")          ----> field .01
        ;"              PtInfo("SEX")                 ----> field .02
        ;"              PtInfo("DOB")                 ----> field .03
        ;"              PtInfo("SSNUM")               ----> field .09
        ;"              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
        ;"      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
 
        new Fields
        ;"Store names indexes of import data to compare with
        set Fields(22701)="PMS ACCOUNT NUM"
        set Fields(.01)="FULL NAME3"
        set Fields(.02)="SEX"
        set Fields(.03)="DOB"
        set Fields(.09)="SSNUM"
        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"
 
        ;"This will be fields to get from VistA for comparison
        ;"For every number there should be a matched entry above.
        set Fields="22701;.01;.02;.03;.09;.111;.112;.113;.115;.114;.1112;.131;.1041"
 
        set Name=$get(PtInfo("FULL NAME3"))
        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)
 
        ;"Add patient to database (register) if appropriate
        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 from database for comparison
        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 do
        . . . . set UpdateNeeded=1
        . . . . 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 UpdateNeeded=1
        . . . . 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)_"PMS#="_PtInfo(field)_" vs. VistA#="_TMGARRAY(2,IENS,index)
        . . . set abort=1,result=0
        . . else  if index=.03 do  ;"compare internal values of DOBs, not external values
        . . . new %DT set %DT="P"  ;"past dates                                        A
        . . . new ddate1,date2
        . . . set X=value do ^%DT set date1=Y;"get internal form of date, store in date1
        . . . set X=$get(TMGARRAY(2,IENS,index))
        . . . do ^%DT set date2=Y;"get internal form of date, store in date2
        . . . if date1'=date2 set NewInfo(.03)=value  ;"dates do differ, so update Vist
        . . . set UpdateNeeded=1
        . . else  do
        . . . 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
 
