1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13  """ 
 14  Implements an interface to a x12 segment. 
 15   
 16  A segment is comprised of a segment identifier and a sequence of elements. 
 17  An element can be a simple element or a composite.  A simple element is  
 18  treated as a composite element with one sub-element. 
 19   
 20  All indexing is zero based. 
 21  """ 
 22   
 23   
 24   
 25  from pyx12.errors import EngineError 
 26   
 28      """ 
 29      Holds a simple element, which is just a simple string. 
 30      """ 
 31   
 33          """ 
 34          @param ele_str: 1::2 
 35          @type ele_str: string 
 36           
 37          """ 
 38          self.value = ele_str 
  39           
 41          """ 
 42          @rtype: int 
 43          """ 
 44          return 1 
  45   
 47          """ 
 48          @rtype: string 
 49          """ 
 50          return self.value 
  51   
 57   
 59          """ 
 60          @rtype: string 
 61          """ 
 62          return self.value 
  63   
 65          """ 
 66          @param elem_str: Element string value 
 67          @type elem_str: string 
 68          """ 
 69          self.value = elem_str 
  70   
 72          """ 
 73          @rtype: boolean 
 74          """ 
 75          return False 
  76    
 78          """ 
 79          @rtype: boolean 
 80          """ 
 81          return True 
  82   
 84          """ 
 85          @rtype: boolean 
 86          """ 
 87          if self.value and self.value != '': 
 88              return False 
 89          else: 
 90              return True 
   91   
 93      """ 
 94      Can be a simple element or a composite. 
 95      A simple element is treated as a composite element with one sub-element. 
 96      """ 
 97       
 98       
 99       
100 -    def __init__(self, ele_str, subele_term=None): 
 101          """ 
102          @type ele_str: string 
103          """ 
104          self.subele_term = subele_term 
105          self.subele_term_orig = subele_term 
106          members = ele_str.split(self.subele_term) 
107          self.elements = [] 
108          for elem in members: 
109              self.elements.append(Element(elem)) 
 110           
112          """ 
113          returns Element instance for idx 
114          """ 
115          return self.elements[idx] 
 116   
118          """ 
119          1 based index 
120          [0] throws exception 
121          sets element value for idx 
122          """ 
123          self.elements[idx] = val 
 124   
126          """ 
127          @rtype: int 
128          """ 
129          return len(self.elements) 
 130   
132          """ 
133          @rtype: string 
134          """ 
135          return self.format(self.subele_term) 
 136   
150               
152          """ 
153          Get value of simple element 
154          """ 
155          if len(self.elements) == 1: 
156              return self.elements[0].get_value() 
157          else: 
158              raise IndexError, 'value of composite is undefined' 
 159   
161          """ 
162          @param subele_term: Sub-element terminator value 
163          @type subele_term: string 
164          """ 
165          self.subele_term = subele_term 
 166     
168          """ 
169          @rtype: boolean 
170          """ 
171          if len(self.elements) > 1: 
172              return True 
173          else: 
174              return False 
 175    
177          """ 
178          @rtype: boolean 
179          """ 
180          if len(self.elements) == 1: 
181              return True 
182          else: 
183              return False 
 184   
186          """ 
187          @rtype: boolean 
188          """ 
189          for ele in self.elements: 
190              if not ele.is_empty(): 
191                  return False 
192          return True 
  193   
194   
196      """ 
197      Encapsulates a X12 segment.  Contains composites. 
198      """ 
199       
200       
201       
202 -    def __init__(self, seg_str, seg_term, ele_term, subele_term): 
 203          """ 
204          """ 
205          self.seg_term = seg_term 
206          self.seg_term_orig = seg_term 
207          self.ele_term = ele_term 
208          self.ele_term_orig = ele_term 
209          self.subele_term = subele_term 
210          self.subele_term_orig = subele_term 
211          self.seg_id = None 
212          if seg_str and seg_str[-1] == seg_term: 
213              elems = seg_str[:-1].split(self.ele_term) 
214          else: 
215              elems = seg_str.split(self.ele_term) 
216          self.elements = [] 
217          if elems: 
218              self.seg_id = elems[0] 
219          for ele in elems[1:]: 
220              if self.seg_id == 'ISA': 
221                   
222                   
223                  self.elements.append(Composite(ele, ele_term)) 
224              else: 
225                  self.elements.append(Composite(ele, subele_term)) 
 226       
228          """ 
229          @rtype: string 
230          """ 
231          return self.format(self.seg_term, self.ele_term, self.subele_term) 
 232       
233   
234   
235   
236   
237   
238   
239   
240   
241   
242   
243   
245          """ 
246          Append a composite to the segment 
247   
248          @param val: String value of composite 
249          @type val: string 
250          """ 
251          self.elements.append(Composite(val, self.subele_term)) 
 252   
254          """ 
255          @rtype: int 
256          """ 
257          return len(self.elements) 
 258       
260          """ 
261          @rtype: string 
262          """ 
263          return self.seg_id 
 264   
266          """ 
267          Format of ref_des: 
268              - a simple element: TST02 
269              - a composite: TST03 where TST03 is a composite 
270              - a sub-element: TST03-2 
271              - or any of the above with the segment ID omitted (02, 03, 03-1) 
272   
273          @param ref_des: X12 Reference Designator 
274          @type ref_des: string 
275          @rtype: tuple(ele_idx, subele_idx) 
276          @raise EngineError: If the given ref_des does not match the segment ID 
277              or if the indexes are not valid integers 
278          """ 
279          if ref_des is None or ref_des == '': 
280              raise EngineError, 'Blank Reference Designator' 
281          if ref_des[0].isalpha(): 
282              if ref_des[:len(self.seg_id)] != self.seg_id: 
283                  err_str = 'Invalid Reference Designator: %s, seg_id: %s' \ 
284                      % (ref_des, self.seg_id) 
285                  raise EngineError, err_str 
286              rest = ref_des[len(self.seg_id):] 
287          else: 
288              rest = ref_des 
289          dash = rest.find('-') 
290          try: 
291              if dash == -1: 
292                  ele_idx = int(rest) - 1 
293                  comp_idx = None 
294              else: 
295                  ele_idx = int(rest[:dash]) - 1 
296                  comp_idx = int(rest[dash+1:]) - 1 
297          except ValueError: 
298              raise EngineError, 'Invalid Reference Designator indexes: %s' \ 
299                  % (ref_des) 
300          return (ele_idx, comp_idx) 
 301   
302 -    def get(self, ref_des): 
 303          """ 
304          @param ref_des: X12 Reference Designator 
305          @type ref_des: string 
306          @return: Element or Composite 
307          @rtype: L{segment.Composite} 
308          """ 
309          (ele_idx, comp_idx) = self._parse_refdes(ref_des) 
310          if ele_idx >= self.__len__(): 
311              return None 
312          if comp_idx is None: 
313              return self.elements[ele_idx] 
314          else: 
315              if comp_idx >= self.elements[ele_idx].__len__(): 
316                  return None 
317              return self.elements[ele_idx][comp_idx] 
 318       
320          """ 
321          @param ref_des: X12 Reference Designator 
322          @type ref_des: string 
323          """ 
324          comp1 = self.get(ref_des) 
325          if comp1 is None: 
326              return None 
327          else: 
328              return comp1.format() 
 329           
331          """ 
332          @param ref_des: X12 Reference Designator 
333          @type ref_des: string 
334          @attention: Deprecated - use get_value 
335          """ 
336          return self.get(ref_des).format() 
 337           
338 -    def set(self, ref_des, val): 
 339          """ 
340          Set the value of an element or subelement identified by the  
341          Reference Designator 
342           
343          @param ref_des: X12 Reference Designator 
344          @type ref_des: string 
345          @param val: New value 
346          @type val: string 
347          """ 
348          (ele_idx, comp_idx) = self._parse_refdes(ref_des) 
349          while len(self.elements) <= ele_idx: 
350              self.elements.append(Composite('', self.subele_term)) 
351          if comp_idx is None: 
352              self.elements[ele_idx] = Composite(val, self.subele_term) 
353          else: 
354              while len(self.elements[ele_idx]) <= comp_idx: 
355                  self.elements[ele_idx].elements.append(Element('')) 
356              self.elements[ele_idx][comp_idx] = Element(val) 
 357   
359          """ 
360          @param ref_des: X12 Reference Designator 
361          @type ref_des: string 
362          """ 
363          ele_idx = self._parse_refdes(ref_des)[0] 
364          return self.elements[ele_idx].is_element() 
 365   
367          """ 
368          @param ref_des: X12 Reference Designator 
369          @type ref_des: string 
370          """ 
371          ele_idx  = self._parse_refdes(ref_des)[0] 
372          return self.elements[ele_idx].is_composite() 
 373   
375          """ 
376          @param ref_des: X12 Reference Designator 
377          @type ref_des: string 
378          @return: number of sub-elements in an element or composite 
379          @rtype: int 
380          """ 
381          ele_idx = self._parse_refdes(ref_des)[0] 
382          return len(self.elements[ele_idx]) 
 383   
385          """ 
386          @param seg_term: Segment terminator 
387          @type seg_term: string 
388          """ 
389          self.seg_term = seg_term 
 390   
392          """ 
393          @param ele_term: Element terminator 
394          @type ele_term: string 
395          """ 
396          self.ele_term = ele_term 
 397   
399          """ 
400          @param subele_term: Sub-element terminator 
401          @type subele_term: string 
402          """ 
403          self.subele_term = subele_term 
 404   
405   
406   
407   
429   
443   
445          """ 
446          @rtype: boolean 
447          """ 
448          if len(self.elements) == 0: 
449              return True 
450          for ele in self.elements: 
451              if not ele.is_empty(): 
452                  return False 
453          return True 
 454           
456          """ 
457          Is the Segment identifier the correct length 
458          @rtype: boolean 
459          """ 
460          if not self.seg_id or len(self.seg_id) < 2 or len(self.seg_id) > 3: 
461              return False 
462          else: 
463              return True 
  464