def test_afregistrering_af_koordinat( firedb: FireDb, sag: Sag, srid: Srid, punkt: Punkt ): """ Database triggeren BID#KOORDINAT sætter registreringtil og sagseventtilid ved indsættelse af ny koordinat. Tjek at triggeren virker. """ se1 = Sagsevent( id=str(uuid.uuid4()), sag=sag, eventtype=EventType.KOORDINAT_BEREGNET ) se1.koordinater = [ Koordinat( srid=srid, punkt=punkt, t=dt.datetime(2020, 5, 13, 8, 0), x=0, y=0, z=0, sx=0, sy=0, sz=0, ) ] firedb.session.add(se1) firedb.session.commit() se2 = Sagsevent( id=str(uuid.uuid4()), sag=sag, eventtype=EventType.KOORDINAT_BEREGNET ) se2.koordinater = [ Koordinat( srid=srid, punkt=punkt, t=dt.datetime(2020, 5, 13, 9, 45), x=1, y=1, z=1, sx=1, sy=1, sz=1, ) ] firedb.session.add(se2) firedb.session.commit() p = firedb.hent_punkt(punkt.id) assert len(p.koordinater) == 2 assert p.koordinater[0].srid.sridid == srid.sridid assert p.koordinater[1].srid.sridid == srid.sridid assert p.koordinater[0].registreringtil == p.koordinater[1].registreringfra assert p.koordinater[0].sagseventtilid == p.koordinater[1].sagseventfraid
def test_fejlmeld_koordinat_midt_i_tidsserie(firedb: FireDb, sag: Sag, punkt: Punkt, srid: Srid): koordinater = [] for i in range(3): se = Sagsevent(id=str(uuid.uuid4()), sag=sag, eventtype=EventType.KOORDINAT_BEREGNET) koordinat = Koordinat( srid=srid, punkt=punkt, _registreringfra=dt.datetime(2020, 9, 22, 8, i), t=dt.datetime(2020, 5, 9, 22, i), x=i, y=i, z=i, sx=0, sy=0, sz=0, ) koordinater.append(koordinat) se.koordinater = [koordinat] firedb.session.add(se) firedb.session.commit() firedb.fejlmeld_koordinat( Sagsevent(sag=sag, eventtype=EventType.KOORDINAT_NEDLAGT), koordinater[1]) assert koordinater[1].fejlmeldt is True assert koordinater[1].registreringtil is not None
def fejlmeld_koordinat(self, sagsevent: Sagsevent, koordinat: Koordinat): """ Fejlmeld en allerede eksisterende koordinat. Hvis koordinaten er den eneste af sin slags på det tilknyttede punkt fejlmeldes og afregistreres den. Hvis koordinaten indgår i en tidsserie sker en af to ting: 1. Hvis koordinaten forekommer midt i en tidsserie fejlmeldes den uden videre. 2. Hvis koordinaten er den seneste i tidsserien fejlmeldes den, den foregående koordinat fejlmeldes og en ny koordinat indsættes med den foregåendes værdier. Denne fremgangsmåde sikrer at der er en aktuel og gyldig koordinat, samt at den samme koordinat ikke fremtræder to gange i en tidsserie. """ punkt = koordinat.punkt srid = koordinat.srid ny_koordinat = None if len(punkt.koordinater) == 1: self._luk_fikspunkregisterobjekt(koordinat, sagsevent, commit=False) # Er koordinaten den sidste i tidsserien? if koordinat.registreringtil is None: # Find seneste ikke-fejlmeldte koordinat så den # bruges som den seneste gyldige koordinat for forrige_koordinat in reversed(punkt.koordinater[0:-1]): if forrige_koordinat.srid != srid: continue if not forrige_koordinat.fejlmeldt: break if not forrige_koordinat.fejlmeldt: ny_koordinat = Koordinat( punktid=forrige_koordinat.punktid, sridid=forrige_koordinat.sridid, x=forrige_koordinat.x, y=forrige_koordinat.y, z=forrige_koordinat.z, t=forrige_koordinat.t, sx=forrige_koordinat.sx, sy=forrige_koordinat.sy, sz=forrige_koordinat.sz, transformeret=forrige_koordinat.transformeret, artskode=forrige_koordinat.artskode, _registreringfra=func.sysdate(), ) sagsevent.koordinater = [ny_koordinat] self.session.add(sagsevent) koordinat.fejlmeldt = True if ny_koordinat: koordinat._registreringtil = ny_koordinat._registreringfra self.session.add(koordinat) self.session.commit()
def test_afregistrering_koordinat(firedb: FireDb, sag: Sag, punkt: Punkt, srid: Srid): """ Test trigger koordinat_au_trg - Automatisk afrestrering af tidligere koordinat. """ k1 = Koordinat( punkt=punkt, srid=srid, x=0, y=0, z=0, sx=0, sy=0, sz=0, t=dt.datetime(2020, 9, 22, 13, 37), ) se = Sagsevent(sag=sag, eventtype=EventType.KOORDINAT_BEREGNET) se.koordinater = [k1] firedb.session.add(se) k2 = Koordinat( punkt=punkt, srid=srid, x=0.1, y=0, z=0, sx=0, sy=0, sz=0, t=dt.datetime(2020, 9, 22, 13, 40), ) se = Sagsevent(sag=sag, eventtype=EventType.KOORDINAT_BEREGNET) se.koordinater = [k2] firedb.session.add(se) firedb.session.commit() assert k1.registreringtil == k2.registreringfra assert k1.sagseventtilid == k2.sagseventfraid assert k2.registreringtil is None assert k2.sagseventtilid is None
def test_fejlmeld_koordinat_midt_i_tidsserie_flere_srider( firedb: FireDb, sag: Sag, punkt: Punkt, srid: Srid): """ Test fejlmeldingslogik i tilfælde af at punktet har koordinater tilhørende flere SRID'er """ srid = [firedb.hent_srid("EPSG:5799"), srid] koordinater = [] for i in range(4): se = Sagsevent(id=str(uuid.uuid4()), sag=sag, eventtype=EventType.KOORDINAT_BEREGNET) koordinat = Koordinat( srid=srid[i % 2], punkt=punkt, _registreringfra=dt.datetime(2020, 9, 22, 8, i), t=dt.datetime(2020, 5, 9, 22, i), x=i, y=i, z=i, sx=0, sy=0, sz=0, ) koordinater.append(koordinat) se.koordinater = [koordinat] firedb.session.add(se) firedb.session.commit() firedb.fejlmeld_koordinat( Sagsevent(sag=sag, eventtype=EventType.KOORDINAT_NEDLAGT), koordinater[3]) assert koordinater[3].fejlmeldt is True assert koordinater[3].registreringtil is not None assert punkt.koordinater[4].registreringtil is None assert punkt.koordinater[4].fejlmeldt is False assert punkt.koordinater[1].x == punkt.koordinater[4].x
def ilæg_nye_koter(projektnavn: str, sagsbehandler: str, **kwargs) -> None: """Registrer nyberegnede koter i databasen""" sag = find_sag(projektnavn) sagsgang = find_sagsgang(projektnavn) sag = find_sag(projektnavn) sagsgang = find_sagsgang(projektnavn) fire.cli.print(f"Sags/projekt-navn: {projektnavn} ({sag.id})") fire.cli.print(f"Sagsbehandler: {sagsbehandler}") punktoversigt = find_faneblad(projektnavn, "Endelig beregning", ARKDEF_PUNKTOVERSIGT) ny_punktoversigt = punktoversigt[0:0] DVR90 = fire.cli.firedb.hent_srid("EPSG:5799") registreringstidspunkt = func.current_timestamp() tid = gyldighedstidspunkt(projektnavn) # Generer sagsevent sagsevent = Sagsevent(sag=sag, id=uuid(), eventtype=EventType.KOORDINAT_BEREGNET) til_registrering = [] opdaterede_punkter = [] for punktdata in punktoversigt.to_dict(orient="records"): # Blanklinje, tilbageholdt, eller allerede registreret? if (pd.isna(punktdata["Ny kote"]) or punktdata["uuid"] != "" or punktdata["Udelad publikation"] == "x"): ny_punktoversigt = ny_punktoversigt.append(punktdata, ignore_index=True) continue punkt = fire.cli.firedb.hent_punkt(punktdata["Punkt"]) opdaterede_punkter.append(punkt) punktdata["uuid"] = sagsevent.id kote = Koordinat( srid=DVR90, punkt=punkt, t=tid, z=punktdata["Ny kote"], sz=punktdata["Ny σ"], ) til_registrering.append(kote) ny_punktoversigt = ny_punktoversigt.append(punktdata, ignore_index=True) if 0 == len(til_registrering): fire.cli.print("Ingen koter at registrere!", fg="yellow", bold=True) return # Vi vil ikke have alt for lange sagseventtekster (bl.a. fordi Oracle ikke # kan lide lange tekststrenge), så vi indsætter udeladelsesprikker hvis vi # opdaterer mere end 10 punkter ad gangen n = len(opdaterede_punkter) punktnavne = [p.ident for p in opdaterede_punkter] if n > 10: punktnavne[9] = "..." punktnavne[10] = punktnavne[-1] punktnavne = punktnavne[0:10] sagseventtekst = f"Opdatering af DVR90 kote til {', '.join(punktnavne)}" with open(f"{projektnavn}-resultat-endelig.html") as html: clob = "".join(html.readlines()) sagseventinfo = SagseventInfo( beskrivelse=sagseventtekst, htmler=[SagseventInfoHtml(html=clob)], ) sagsevent.sagseventinfos.append(sagseventinfo) sagsevent.koordinater = til_registrering fire.cli.firedb.indset_sagsevent(sagsevent, commit=False) # Generer dokumentation til fanebladet "Sagsgang" # Variablen "registreringstidspunkt" har værdien "CURRENT_TIMESTAMP" # som udvirker mikrosekundmagi når den bliver skrevet til databasen, # men ikke er meget informativ for en menneskelig læser her i regne- # arkenes prosaiske verden. Derfor benytter vi pd.Timestamp.now(), # som ikke har mikrosekundmagi over sig, men som kan læses og giver # mening, selv om den ikke bliver eksakt sammenfaldende med det # tidsstempel hændelsen får i databasen. Det lever vi med. sagsgangslinje = { "Dato": pd.Timestamp.now(), "Hvem": sagsbehandler, "Hændelse": "Koteberegning", "Tekst": sagseventtekst, "uuid": sagsevent.id, } sagsgang = sagsgang.append(sagsgangslinje, ignore_index=True) fire.cli.print(sagseventtekst, fg="yellow", bold=True) fire.cli.print(f"Ialt {n} koter") try: fire.cli.firedb.session.flush() except Exception as ex: # rul tilbage hvis databasen smider en exception fire.cli.firedb.session.rollback() fire.cli.print( f"Der opstod en fejl - koter for '{projektnavn}' IKKE indlæst!") fire.cli.print(f"Mulig årsag: {ex}") else: spørgsmål = click.style("Du indsætter nu ", fg="white", bg="red") spørgsmål += click.style(f"{len(til_registrering)} kote(r) ", fg="white", bg="red", bold=True) spørgsmål += click.style(f"i ", fg="white", bg="red") spørgsmål += click.style(f"{fire.cli.firedb.db}", fg="white", bg="red", bold=True) spørgsmål += click.style("-databasen - er du sikker?", fg="white", bg="red") if bekræft(spørgsmål): fire.cli.firedb.session.commit() # Skriv resultater til resultatregneark resultater = {"Sagsgang": sagsgang, "Resultat": ny_punktoversigt} if skriv_ark(projektnavn, resultater): fire.cli.print( f"Koter registreret. Resultater skrevet til '{projektnavn}.xlsx'" )