def change(self, where, change): """ where: node to find. change is applied to found node uses first matching node for 'where'. """ self._mpath_sanity_check(where) for part in where: if "BOTSIDnr" not in part: part["BOTSIDnr"] = "1" # sanity check 'change' parameter if not isinstance(change, dict): raise MappingFormatError( _('Parameter "change" must be dict: change(where=%(where)s,change=%(change)s)' ), { "where": where, "change": change }, ) change.pop( "BOTSID", "nep") # remove 'BOTSID' from change. BOTSID can not be changed change.pop( "BOTSIDnr", "nep" ) # remove 'BOTSIDnr' from change. BOTSIDnr can not be changed for key, value in change.items(): if not isinstance(key, str): raise MappingFormatError( _('Keys in "change" must be strings: change(where=%(where)s,change=%(change)s)' ), { "where": where, "change": change }, ) if value is None: # if None, item is deleted pass elif isinstance(value, list): # for now, just pass lists pass else: change[key] = str(value).strip( ) # leading and trailing spaces are stripped from the values terug = self._changecore(where, change) logmap.debug( '"%(terug)s" for change(where=%(where)s,change=%(change)s)', { "terug": terug, "where": str(where), "change": str(change) }, ) return terug
def get(self, *mpaths): """ get value of a field in a record from a edi-message mpath is xpath-alike query to identify the record/field function returns 1 value; return None if nothing found. if more than one value can be found: first one is returned starts searching in current node, then deeper """ if Node.checklevel: self._mpath_sanity_check(mpaths[:-1]) # sanity check of last part of mpaths: None only allowed in last section of Mpath; check last part if not isinstance(mpaths[-1], dict): raise MappingFormatError( _("Must be dicts in tuple: get(%(mpath)s)"), {"mpath": mpaths}) if "BOTSID" not in mpaths[-1]: raise MappingFormatError( _('Last section without "BOTSID": get(%(mpath)s)'), {"mpath": mpaths}, ) count = 0 for key, value in mpaths[-1].items(): if not isinstance(key, str): raise MappingFormatError( _("Keys must be strings in last section: get(%(mpath)s)" ), {"mpath": mpaths}, ) if value is None: count += 1 elif not isinstance(value, str): raise MappingFormatError( _("Values must be strings (or none) in last section: get(%(mpath)s)" ), {"mpath": mpaths}, ) if count > 1: raise MappingFormatError( _('Max one "None" in last section: get(%(mpath)s)'), {"mpath": mpaths}, ) for part in mpaths: if "BOTSIDnr" not in part: part["BOTSIDnr"] = "1" if Node.checklevel == 2: self._mpath_grammar_check(mpaths) terug = self._getcore(mpaths) logmap.debug('"%(terug)s" for get%(mpaths)s', { "terug": terug, "mpaths": str(mpaths) }) return terug
def getrecord(self, *mpaths): """ get whole node record """ self._mpath_sanity_check(mpaths) for part in mpaths: if "BOTSIDnr" not in part: part["BOTSIDnr"] = "1" terug = self._getrecordcore(mpaths) logmap.debug( '"%(terug)s" for getrecord%(mpaths)s', { "terug": str(terug), "mpaths": str(mpaths) }, ) return terug
def checkenvelope(self): for nodestx in self.getloop({"BOTSID": "STX"}): logmap.debug("Start parsing tradacoms envelopes") endcount = nodestx.get({"BOTSID": "STX"}, { "BOTSID": "END", "NMST": None }) messagecount = len(nodestx.children) - 1 try: if int(endcount) != messagecount: self.add2errorlist( _("[E22]: Count in END is %(endcount)s; should be equal to number of messages %(messagecount)s.\n" ) % { "endcount": endcount, "messagecount": messagecount }) except: self.add2errorlist( _('[E23]: Count of messages in END is invalid: "%(count)s".\n' ) % {"count": endcount}) firstmessage = True for nodemhd in nodestx.getloop({"BOTSID": "STX"}, {"BOTSID": "MHD"}): if firstmessage: nodestx.queries = { "messagetype": nodemhd.queries["messagetype"] } firstmessage = False mtrcount = nodemhd.get({"BOTSID": "MHD"}, { "BOTSID": "MTR", "NOSG": None }) segmentcount = nodemhd.getcount() try: if int(mtrcount) != segmentcount: self.add2errorlist( _("[E24]: Count in MTR is %(mtrcount)s; should be equal to number of segments %(segmentcount)s.\n" ) % { "mtrcount": mtrcount, "segmentcount": segmentcount }) except: self.add2errorlist( _('[E25]: Count of segments in MTR is invalid: "%(count)s".\n' ) % {"count": mtrcount}) logmap.debug("Parsing tradacoms envelopes is TransactionStatus.OK")
def delete(self, *mpaths): """ delete the last record of mpath if found (first: find/identify record, than delete).""" self._mpath_sanity_check(mpaths) if len(mpaths) == 1: raise MappingFormatError( _("Only one dict: not allowed. Use different solution: delete(%(mpath)s)" ), {"mpath": mpaths}, ) for part in mpaths: if "BOTSIDnr" not in part: part["BOTSIDnr"] = "1" terug = bool(self._deletecore(mpaths)) logmap.debug('"%(terug)s" for delete%(mpaths)s', { "terug": terug, "mpaths": str(mpaths) }) return terug # return False if not removed, return True if removed
def getloop(self, *mpaths): """ generator. Returns one by one the nodes as indicated in mpath """ if Node.checklevel: self._mpath_sanity_check(mpaths) for part in mpaths: if "BOTSIDnr" not in part: part["BOTSIDnr"] = "1" if Node.checklevel == 2: self._mpath_grammar_check(mpaths) for terug in self._getloopcore(mpaths): logmap.debug( 'getloop %(mpaths)s returns "%(record)s".', { "mpaths": mpaths, "record": terug.record }, ) yield terug
def getloop_including_mpath(self, *mpaths): """ generator. Returns one by one the nodes as indicated in mpath like getloop(), but returns a list: [mpath,mpath,etc,,node] ->node is same as returned by getloop() """ if Node.checklevel: self._mpath_sanity_check(mpaths) for part in mpaths: if "BOTSIDnr" not in part: part["BOTSIDnr"] = "1" if Node.checklevel == 2: self._mpath_grammar_check(mpaths) for terug in self._getloopcore_including_mpath(mpaths): logmap.debug( 'getloop %(mpaths)s returns "%(terug)s".', { "mpaths": mpaths, "terug": terug }, ) yield terug
def put(self, *mpaths, **kwargs): # sanity check of mpaths if not mpaths or not isinstance(mpaths, tuple): raise MappingFormatError( _("Must be dicts in tuple: put(%(mpath)s)"), {"mpath": mpaths}) for part in mpaths: if not isinstance(part, dict): raise MappingFormatError( _("Must be dicts in tuple: put(%(mpath)s)"), {"mpath": mpaths}) if "BOTSID" not in part: raise MappingFormatError( _('Section without "BOTSID": put(%(mpath)s)'), {"mpath": mpaths}) for key, value in part.items(): if value is None: logmap.debug('"None" in put %(mpaths)s.', {"mpaths": str(mpaths)}) return False if not isinstance(key, str): raise MappingFormatError( _("Keys must be strings: put(%(mpath)s)"), {"mpath": mpaths}) if isinstance(value, list): # empty is not useful, drop it (like None) if not value: logmap.debug("Empty list in put %(mpaths)s.", {"mpaths": str(mpaths)}) return False else: if kwargs.get("strip", True): part[key] = str(value).strip( ) # leading and trailing spaces are stripped from the values else: part[key] = str( value) # used for fixed ISA header of x12 if "BOTSIDnr" not in part: part["BOTSIDnr"] = "1" if self._sameoccurence(mpaths[0]): self._putcore(mpaths[1:]) else: raise MappingRootError(_('Error in root put "%(mpath)s".'), {"mpath": mpaths[0]}) logmap.debug('"True" for put %(mpaths)s', {"mpaths": str(mpaths)}) return True
def checkenvelope(self): """ check envelopes (UNB-UNZ counters & references, UNH-UNT counters & references etc) """ for nodeunb in self.getloop({"BOTSID": "UNB"}): logmap.debug("Start parsing edifact envelopes") unbreference = nodeunb.get({"BOTSID": "UNB", "0020": None}) unzreference = nodeunb.get({"BOTSID": "UNB"}, { "BOTSID": "UNZ", "0020": None }) if unbreference and unzreference and unbreference != unzreference: self.add2errorlist( _('[E01]: UNB-reference is "%(unbreference)s"; should be equal to UNZ-reference "%(unzreference)s".\n' ) % { "unbreference": unbreference, "unzreference": unzreference }) unzcount = nodeunb.get({"BOTSID": "UNB"}, { "BOTSID": "UNZ", "0036": None }) messagecount = len(nodeunb.children) - 1 try: if int(unzcount) != messagecount: self.add2errorlist( _("[E02]: Count of messages in UNZ is %(unzcount)s; should be equal to number of messages %(messagecount)s.\n" ) % { "unzcount": unzcount, "messagecount": messagecount }) except: self.add2errorlist( _('[E03]: Count of messages in UNZ is invalid: "%(count)s".\n' ) % {"count": unzcount}) for nodeunh in nodeunb.getloop({"BOTSID": "UNB"}, {"BOTSID": "UNH"}): unhreference = nodeunh.get({"BOTSID": "UNH", "0062": None}) untreference = nodeunh.get({"BOTSID": "UNH"}, { "BOTSID": "UNT", "0062": None }) if unhreference and untreference and unhreference != untreference: self.add2errorlist( _('[E04]: UNH-reference is "%(unhreference)s"; should be equal to UNT-reference "%(untreference)s".\n' ) % { "unhreference": unhreference, "untreference": untreference }) untcount = nodeunh.get({"BOTSID": "UNH"}, { "BOTSID": "UNT", "0074": None }) segmentcount = nodeunh.getcount() try: if int(untcount) != segmentcount: self.add2errorlist( _("[E05]: Segmentcount in UNT is %(untcount)s; should be equal to number of segments %(segmentcount)s.\n" ) % { "untcount": untcount, "segmentcount": segmentcount }) except: self.add2errorlist( _('[E06]: Count of segments in UNT is invalid: "%(count)s".\n' ) % {"count": untcount}) for nodeung in nodeunb.getloop({"BOTSID": "UNB"}, {"BOTSID": "UNG"}): ungreference = nodeung.get({"BOTSID": "UNG", "0048": None}) unereference = nodeung.get({"BOTSID": "UNG"}, { "BOTSID": "UNE", "0048": None }) if ungreference and unereference and ungreference != unereference: self.add2errorlist( _('[E07]: UNG-reference is "%(ungreference)s"; should be equal to UNE-reference "%(unereference)s".\n' ) % { "ungreference": ungreference, "unereference": unereference }) unecount = nodeung.get({"BOTSID": "UNG"}, { "BOTSID": "UNE", "0060": None }) groupcount = len(nodeung.children) - 1 try: if int(unecount) != groupcount: self.add2errorlist( _("[E08]: Groupcount in UNE is %(unecount)s; should be equal to number of groups %(groupcount)s.\n" ) % { "unecount": unecount, "groupcount": groupcount }) except: self.add2errorlist( _('[E09]: Groupcount in UNE is invalid: "%(count)s".\n' ) % {"count": unecount}) for nodeunh in nodeung.getloop({"BOTSID": "UNG"}, {"BOTSID": "UNH"}): unhreference = nodeunh.get({"BOTSID": "UNH", "0062": None}) untreference = nodeunh.get({"BOTSID": "UNH"}, { "BOTSID": "UNT", "0062": None }) if unhreference and untreference and unhreference != untreference: self.add2errorlist( _('[E10]: UNH-reference is "%(unhreference)s"; should be equal to UNT-reference "%(untreference)s".\n' ) % { "unhreference": unhreference, "untreference": untreference, }) untcount = nodeunh.get({"BOTSID": "UNH"}, { "BOTSID": "UNT", "0074": None }) segmentcount = nodeunh.getcount() try: if int(untcount) != segmentcount: self.add2errorlist( _("[E11]: Segmentcount in UNT is %(untcount)s; should be equal to number of segments %(segmentcount)s.\n" ) % { "untcount": untcount, "segmentcount": segmentcount }) except: self.add2errorlist( _('[E12]: Count of segments in UNT is invalid: "%(count)s".\n' ) % {"count": untcount}) logmap.debug("Parsing edifact envelopes is TransactionStatus.OK")