Steve Nyemba 1 year ago
parent
commit
3eb5c5b568

+ 8 - 4
healthcareio/x12/plugins/default/__init__.py

@@ -1,5 +1,6 @@
 """
 """
-This file serves as the interface (so to speak) to the x12 parser, plugin interface
+This file serves as the interface (so to speak) to the x12 parser, plugin interface, We implement default plugins that will handle parsing,
+In addition to the allow custom plugins to be written/loaded and these will be given priority over the default ones+6+++++++++++++++++++++++++++++++++++++++++++++++++
 @TODO:
 @TODO:
     - How to write custom plugin
     - How to write custom plugin
     - Provide interface for meta-data (expected)
     - Provide interface for meta-data (expected)
@@ -11,11 +12,14 @@ from . import header
 from . import body
 from . import body
 
 
 EDI = body.BODY
 EDI = body.BODY
-
+__version__ = '0.01'
+__author__ = 'The Phi Technology'
 def instance(**_args):
 def instance(**_args):
     pass
     pass
-
-# class Parser :
+#
+# defining commong functions that can/should be used accross the board
+#
+# # class Parser :
 #     def __init__(**_args):
 #     def __init__(**_args):
 #         folder = _args['path']
 #         folder = _args['path']
 #         files = [ os.sep.join(_name,folder) for _name in os.listdir(folder)]
 #         files = [ os.sep.join(_name,folder) for _name in os.listdir(folder)]

+ 15 - 2
healthcareio/x12/plugins/default/body.py

@@ -21,16 +21,29 @@ class BODY (HEADER):
         ref IL,40,41,82,85,PR ...
         ref IL,40,41,82,85,PR ...
         Information about entities (doctors, clearing house, provider). we should be mindful of the references
         Information about entities (doctors, clearing house, provider). we should be mindful of the references
         """
         """
-        # _CODE_INDEX = 1
+        _CODE_INDEX = 1
+        CONTEXT_MAP = {
+            
+                '2':{'field':'payer'},
+                'PR':{'field':'payer'},
+                '41':{'field':'header'},
+                'IL':{'field':'patient','map':{'type':2,'first_name':4,'last_name':3}},
+                'P5':{'field':'plan_sponsor'},
+                '82':{'field':'rendering_provider','map':{'type':2,'first_name':4,'last_name':3}},
+                '85':{'field':'billing_provider'}
+            
+        }
+        _args ['plugin-context'] = {'@ref':CONTEXT_MAP}
         # _map = {_CODE_INDEX:{'41':'submitter','40':'receiver','PR':'payer'}} 
         # _map = {_CODE_INDEX:{'41':'submitter','40':'receiver','PR':'payer'}} 
         _columns = ['type','name','id']  
         _columns = ['type','name','id']  
         _indexes = [1,3,-1]    
         _indexes = [1,3,-1]    
         # _info = [{'index':'40','field':'receiver'},{'index':'41','field':'submitter'},{'index':'PR','field':'payer'}]
         # _info = [{'index':'40','field':'receiver'},{'index':'41','field':'submitter'},{'index':'PR','field':'payer'}]
         
         
         _info =  self.parse(_columns,_indexes,**_args)    
         _info =  self.parse(_columns,_indexes,**_args)    
+        self.lastelement = _info
         return _info
         return _info
     def N3 (self,**_args):
     def N3 (self,**_args):
-        """
+        """        
         Expected Element N3
         Expected Element N3
         """
         """
         
         

+ 78 - 33
healthcareio/x12/plugins/default/common.py

@@ -74,7 +74,7 @@ class X12DOCUMENT (Process):
             _field = _config['field'] if 'field' in _config else {}
             _field = _config['field'] if 'field' in _config else {}
             _label = _config['label'] if 'label' in _config else {}
             _label = _config['label'] if 'label' in _config else {}
             return _field,_label
             return _field,_label
-        def merge(self,**_args):
+        def consolidate(self,**_args):
             #
             #
             # This function overrides the old configuration with the new configuration specifications
             # This function overrides the old configuration with the new configuration specifications
             #
             #
@@ -92,24 +92,28 @@ class X12DOCUMENT (Process):
             if '@ref' in _config :
             if '@ref' in _config :
                 # _columns,_indexes = [],[]
                 # _columns,_indexes = [],[]
                 _row = _args['row']  
                 _row = _args['row']  
-                        
-                _ref = _config['@ref']
+                
+                _ref = _config['@ref']              
                 
                 
                 for _anchor in _ref:
                 for _anchor in _ref:
-                    # print ([_anchor,_anchor == _row[1].strip()])
+                    
                     if _anchor == _row[1].strip() :
                     if _anchor == _row[1].strip() :
                         _field,_label = self._getObjectAtributes(_ref[_anchor])
                         _field,_label = self._getObjectAtributes(_ref[_anchor])
                         
                         
                         _map = _ref[_anchor]['map'] if 'map' in _ref[_anchor] else {}
                         _map = _ref[_anchor]['map'] if 'map' in _ref[_anchor] else {}
-                        
+                       
                         if _map :
                         if _map :
                             _columns,_indexes = self._getColumnsIndexes([],[],_map)
                             _columns,_indexes = self._getColumnsIndexes([],[],_map)
-                           
+                        else:
+                            # print ([_anchor,_indexes,_columns])  
+                            _map = dict(zip(_columns,_indexes))
+                            pass
                            
                            
                         break
                         break
                 # _columns,_indexes = _columns + _map.keys()
                 # _columns,_indexes = _columns + _map.keys()
                
                
-            return {'columns':_columns,'index':_indexes,'field':_field,'label':_label}
+            _out =  {'columns':_columns,'index':_indexes,'field':_field,'label':_label}
+            return _out
         def legacy(self,**_args):
         def legacy(self,**_args):
             #
             #
             # This function returns the legacy configuration (default parsing)
             # This function returns the legacy configuration (default parsing)
@@ -128,9 +132,17 @@ class X12DOCUMENT (Process):
     def __init__(self,**_args):
     def __init__(self,**_args):
         super().__init__()
         super().__init__()
         self._mode = _args['mode'] if 'mode' in _args else 'NAMES'
         self._mode = _args['mode'] if 'mode' in _args else 'NAMES'
+        self.lastelement = {}  # This to store in the loop
         if 'files' in _args :
         if 'files' in _args :
             self.files = _args['files']
             self.files = _args['files']
         self._config = _args['config'] if 'config' in _args else {}
         self._config = _args['config'] if 'config' in _args else {}
+        
+        #
+        # NM1 is a fluid type and thus will be cached in order to recreate the hierarchy
+        # @TODO:
+        #   -add this to the configuration
+        #
+        self._hierarchy = {'NM1':['N1','N2','N3','N4']}
         self._document = []
         self._document = []
         
         
         self._x12FileType = None
         self._x12FileType = None
@@ -218,8 +230,16 @@ class X12DOCUMENT (Process):
         # _field = _field if not _refField else _refField
         # _field = _field if not _refField else _refField
         # _label = _label if not _refLabel else _refLabel
         # _label = _label if not _refLabel else _refLabel
         
         
-        _outInfo = self._configHandler.merge(row=_args['row'],columns=columns,index=index,config=_config)
+        #
+        # @TODO:
+        # There should be a priority in parsing i.e plugin - config
+        #
+        if 'plugin-context' in _args :
+            _config = _args['plugin-context'] #dict(_config,**_args['plugin-context'])
+            
+        _outInfo = self._configHandler.consolidate(row=_args['row'],columns=columns,index=index,config=_config)
         
         
+            
         _field,_label = _outInfo['field'],_outInfo['label']
         _field,_label = _outInfo['field'],_outInfo['label']
         _columns,_index = _outInfo['columns'],_outInfo['index']
         _columns,_index = _outInfo['columns'],_outInfo['index']
                           
                           
@@ -240,42 +260,61 @@ class X12DOCUMENT (Process):
             
             
             # _element = _row[0]
             # _element = _row[0]
 
 
-            _configKeys = [] #list(self._config.keys())
-            _configTree = [] #list(self._config.values())
-            if 'config' in _args :
-                _config = _args['config']
-                _configKeys = list(_config.keys())
-                _configTree = list(_config.values())
-            else:
-                _config = {}
+            # _configKeys = [] #list(self._config.keys())
+            # _configTree = [] #list(self._config.values())
+            # if 'config' in _args :
+            #     _config = _args['config']
+            #     _configKeys = list(_config.keys())
+            #     _configTree = list(_config.values())
+            # else:
+            #     _config = {}
             
             
             _info =  dict(zip(_columns,_row[_index].tolist()))           
             _info =  dict(zip(_columns,_row[_index].tolist()))           
             _document = _args['document'] if 'document' in _args else {}
             _document = _args['document'] if 'document' in _args else {}
+           
+            #
+            # @TODO:
+            # Apply parsing/casting function to the object retrieved
+            #    _apply(_info)   #-- the object will be processed accordingly
             #
             #
-            # Extracting configuration (minimal information)
-            # _config = _args['config'] if 'config' in _args else {}
-            # _config = self._config
-            
- 
-            # if '@ref' in _config :
-            #     print (_config['@ref'])
-            #     _values = _config['@ref']
-            #     print (_values)
             
             
+            #
+            # @TODO:
+            #   The objects parsed must be augmented against the appropriate ones e.g: NM1 <- N1,N2,N3,N4
+            #   - Find a way to drive this from a configuration ...
+            #
             if _field  :
             if _field  :
+
                 if not  _field in _document :
                 if not  _field in _document :
-                    return {_field:_info}
+                    _item =  {_field:_info}
                 else:
                 else:
-                    return self.merge(_document[_field],_info)
+                    _item =  self.merge(_document[_field],_info)
             elif _label :
             elif _label :
                 if not _label in _document :
                 if not _label in _document :
-                    return {_label:[_info]}
+                    _item =  {_label:[_info]}
                 else:
                 else:
-                    return _document[_label] + [_info]
+                    _item =  _document[_label] + [_info]
             else:
             else:
-                return _info
+                _item =  _info
  
  
+            if _ELEMENT in self._hierarchy  and _field:
+                # print ([_field,_item])
+                self.lastelement = _item
+                pass
+            else:
+                for key in self._hierarchy :
+                    if _ELEMENT in self._hierarchy[key] :
+                        
+                        _ikey       = list(self.lastelement.keys())[0]
+                        _oldinfo    = self.lastelement[_ikey]
+                        _item  = {_ikey: self.merge(_oldinfo,_item)}
+                        
+                        break
+            return _item
         else:
         else:
+            #
+            #
+            print (_config)
             return columns    
             return columns    
     def elements(self):
     def elements(self):
         """
         """
@@ -347,16 +386,22 @@ class X12DOCUMENT (Process):
                 _header = self.apply(_info['header'])
                 _header = self.apply(_info['header'])
                 
                 
                 # print (json.dumps(_header))
                 # print (json.dumps(_header))
+                _tmp = {}
                 for _content in _info['blocks'] :
                 for _content in _info['blocks'] :
                     
                     
-                    _body = self.apply(_content,header=_header)                       
+                    _body = self.apply(_content,header=_header)  
+                                      
                     _doc = self.merge(_header,_body)
                     _doc = self.merge(_header,_body)
                     
                     
                     if _doc  and 'claim_id' in _doc:                    
                     if _doc  and 'claim_id' in _doc:                    
                         # X12DOCUMENT._queue.put(_document)
                         # X12DOCUMENT._queue.put(_document)
                     
                     
-                        _documents += [_doc]
-                
+                        _documents += [self.merge(_tmp,_doc)]
+                        _tmp = {}
+                    else:
+                        #
+                        # The document is being built and not yet ready
+                        _tmp = self.merge(_tmp,_doc)                
                 
                 
             except Exception as e:
             except Exception as e:
                 #
                 #