adapt customer requirements, REQ 1006, 1007

This commit is contained in:
2026-07-28 08:27:45 +02:00
parent 449d401c04
commit a515f3b820
7 changed files with 100 additions and 176 deletions
@@ -0,0 +1,48 @@
"""update schema to meet customer requirements
Revision ID: 5dfa1fc1dfdf
Revises: e290fe18132d
Create Date: 2026-07-28 08:39:44.168872
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision: str = "5dfa1fc1dfdf"
down_revision: Union[str, Sequence[str], None] = "e290fe18132d"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table("Grunderfassung_Personen", schema=None) as batch_op:
batch_op.add_column(
sa.Column("Stammdaten__kanal_aufmerksamkeit", sa.Text(), nullable=True)
)
with op.batch_alter_table("Personen_Unternehmen_Zuordnung", schema=None) as batch_op:
batch_op.add_column(sa.Column("Partnersuche__kontaktweg", sa.Text(), nullable=True))
batch_op.drop_column("Partnersuche__kanal_aufmerksamkeit")
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table("Personen_Unternehmen_Zuordnung", schema=None) as batch_op:
batch_op.add_column(
sa.Column("Partnersuche__kanal_aufmerksamkeit", sa.TEXT(), nullable=True)
)
batch_op.drop_column("Partnersuche__kontaktweg")
with op.batch_alter_table("Grunderfassung_Personen", schema=None) as batch_op:
batch_op.drop_column("Stammdaten__kanal_aufmerksamkeit")
# ### end Alembic commands ###
+2 -1
View File
@@ -15,7 +15,7 @@ Personen_Unternehmen_Zuordnung
pers_id int pk -> Grunderfassung_Personen(pers_id) unique=uq_aktive_zuordnung
un_id int -> Unternehmen(un_id) unique=uq_aktive_zuordnung | alias 'Partnersuche__un_suche'
an_id int -> Ext_Kontaktliste.Ansprechpartner(an_id) | alias 'Partnersuche__person_suche
Partnersuche__kanal_aufmerksamkeit text nullable
Partnersuche__kontaktweg text nullable
erstellt "timestamp with time zone"=`datetime.datetime.now(datetime.UTC)`
aktualisiert "timestamp with time zone"=`datetime.datetime.now(datetime.UTC)` {on_update: `datetime.datetime.now(datetime.UTC)`}
geloescht "timestamp with time zone" nullable | Soft-Delete Marker (partieller Unique-Index: WHERE geloescht IS NULL)
@@ -45,6 +45,7 @@ Grunderfassung_Personen
Projektrelevanz__relevanz text nullable
Projektrelevanz__foerderperiode text nullable
Schulbildung text nullable
Stammdaten__kanal_aufmerksamkeit text nullable
Stammdaten__PLZ text nullable
Stammdaten__anrede_anschrift text nullable
Stammdaten__anzahl_kinder__alter text nullable
+3 -3
View File
@@ -506,7 +506,7 @@ def page_initrec_to_db(
index_where=sa.text("geloescht IS NULL"),
set_={
"an_id": stmt.excluded.an_id,
"Partnersuche__kanal_aufmerksamkeit": stmt.excluded.Partnersuche__kanal_aufmerksamkeit,
"Partnersuche__kontaktweg": stmt.excluded.Partnersuche__kontaktweg,
"aktualisiert": datetime.datetime.now(datetime.UTC),
"geloescht": data.geloescht,
},
@@ -541,7 +541,7 @@ def page_initrec_from_db(
db.t_zuordnung_personen_unternehmen.c.pers_id,
db.t_zuordnung_personen_unternehmen.c.un_id,
db.t_zuordnung_personen_unternehmen.c.an_id,
db.t_zuordnung_personen_unternehmen.c.Partnersuche__kanal_aufmerksamkeit,
db.t_zuordnung_personen_unternehmen.c.Partnersuche__kontaktweg,
).where(
db.t_zuordnung_personen_unternehmen.c.id == ids.link_id,
)
@@ -552,7 +552,7 @@ def page_initrec_from_db(
db.t_zuordnung_personen_unternehmen.c.pers_id,
db.t_zuordnung_personen_unternehmen.c.un_id,
db.t_zuordnung_personen_unternehmen.c.an_id,
db.t_zuordnung_personen_unternehmen.c.Partnersuche__kanal_aufmerksamkeit,
db.t_zuordnung_personen_unternehmen.c.Partnersuche__kontaktweg,
).where(
db.t_zuordnung_personen_unternehmen.c.pers_id == ids.pers_id,
db.t_zuordnung_personen_unternehmen.c.un_id == ids.un_id,
+2 -1
View File
@@ -564,7 +564,7 @@ class Grunderfassung_PartnerSuche(BaseModel):
un_suche: int | None
person_suche: int | None
kanal_aufmerksamkeit: str | None
kontaktweg: str | None
class Grunderfassung_Projektrelevanz(BaseModel):
@@ -592,6 +592,7 @@ class Grunderfassung_Kontaktperson(BaseModel):
class Grunderfassung_Stammdaten(BaseModel):
model_config = ConfigDict(str_strip_whitespace=True)
kanal_aufmerksamkeit: str | None
titel: str | None
anrede_anschrift: str
name: str
+3 -28
View File
@@ -397,19 +397,6 @@ t_grunderfassung_personen: Table = Table(
UTCDateTime,
nullable=True,
),
# Column(
# "Metadaten_erstellung",
# UTCDateTime,
# nullable=True,
# default=lambda: datetime.datetime.now(datetime.UTC),
# ),
# Column(
# "Metadaten_aktualisierung",
# UTCDateTime,
# nullable=True,
# default=lambda: datetime.datetime.now(datetime.UTC),
# onupdate=lambda: datetime.datetime.now(datetime.UTC),
# ),
Column("Metadaten_nutzer", sa.String(20), nullable=True),
Column("Metadaten_wiedereintrittsdatum", sa.Date, nullable=True, default=None),
Column("Arbeitserfahrung", sa.Text, nullable=True),
@@ -423,15 +410,14 @@ t_grunderfassung_personen: Table = Table(
Column("Kontaktperson__KP_funktion_beziehung", sa.Text, nullable=True),
Column("Kontaktperson__KP_mobilfunknummer", sa.Text, nullable=True),
Column("Kontaktperson__KP_name", sa.Text, nullable=True),
Column(
"Kontaktperson__KP_name_partner", sa.Text, nullable=True
), # TODO: check if needed when set by trigger
Column("Kontaktperson__KP_name_partner", sa.Text, nullable=True),
Column("Kontaktperson__KP_titel", sa.Text, nullable=True),
Column("Kontaktperson__KP_vorname", sa.Text, nullable=True),
Column("Projektrelevanz__relevanz", sa.Text, nullable=True),
Column("Projektrelevanz__foerderperiode", sa.Text, nullable=True),
Column("Schulbildung", sa.Text, nullable=True),
Column("Sprachkenntnisse", sa.Text, nullable=True),
Column("Stammdaten__kanal_aufmerksamkeit", sa.Text, nullable=True),
Column("Stammdaten__PLZ", sa.Text, nullable=True),
Column("Stammdaten__anrede_anschrift", sa.Text, nullable=True),
Column("Stammdaten__anzahl_kinder__alter", sa.Text, nullable=True),
@@ -490,18 +476,7 @@ t_zuordnung_personen_unternehmen: Table = Table(
UTCDateTime,
nullable=True,
),
Column("Partnersuche__kanal_aufmerksamkeit", sa.Text, nullable=True),
# Column(
# "gueltig_ab",
# UTCDateTime,
# nullable=False,
# default=lambda: datetime.datetime.now(datetime.UTC),
# ),
# Column(
# "gueltig_bis",
# UTCDateTime,
# nullable=True,
# ),
Column("Partnersuche__kontaktweg", sa.Text, nullable=True),
Index(
"uq_aktive_zuordnung",
"un_id",
+34 -132
View File
@@ -307,53 +307,38 @@ _INITREC_COMP_SEARCH_HEAD = [
info="an_position",
),
FormField(
"Wie sind Sie auf uns aufmerksam geworden?",
"Kontaktweg",
FormFieldType.DROPDOWN,
required=False,
key="kanal_aufmerksamkeit",
key="kontaktweg",
options=[
("Agentur für Arbeit", None),
("Ausländerbehörde", None),
("Jobcenter", None),
("Freunde/Familie", None),
("Anerkennungsstelle", None),
("Beratungsstelle", None),
("Internet", None),
("Arbeitgeber", None),
("Bildungsdienstleister", None),
("Welcome-Mappe", None),
("Newsletter WFE", None),
("Newsletter RM", None),
("Sonstiges", None),
("Telefon", None),
("Mail", None),
("Persönliches Gespräch", None),
],
),
]
_INITREC_CONTACT_PERSON = [
# TODO check removal
FormField(
"Name Unternehmen/Netzwerkpartner (vorausgefüllt von Suche)",
"Name Unternehmen/Netzwerkpartner",
FormFieldType.TEXT,
key="KP_name_partner",
required=False,
placeholder="[TODO: Logik in Verbindung mit Unternehmen unklar]",
readonly=True,
readonly=False,
),
FormField(
"Titel",
FormFieldType.TEXT,
key="KP_titel",
required=False,
tooltip=(
"* nur wenn anrufende Person oder kontaktaufnehmende Person "
"nicht die zu beratende Person ist"
),
),
FormField(
"Anrede_Anschrift",
FormFieldType.TEXT,
"Anrede",
FormFieldType.DROPDOWN,
key="KP_anrede_anschrift",
required=True,
options=[("Sehr geehrte Frau", None), ("Sehr geehrter Herr", None)],
),
FormField(
"Name",
@@ -401,21 +386,39 @@ _INITREC_CONTACT_PERSON = [
_INITREC_MASTER_DATA = [
FormField(
"Wie sind Sie auf uns aufmerksam geworden?",
FormFieldType.DROPDOWN,
required=False,
key="kanal_aufmerksamkeit",
options=[
("Agentur für Arbeit", None),
("Ausländerbehörde", None),
("Jobcenter", None),
("Freunde/Familie", None),
("Anerkennungsstelle", None),
("Beratungsstelle", None),
("Internet", None),
("Arbeitgeber", None),
("Bildungsdienstleister", None),
("Welcome-Mappe", None),
("Newsletter WFE", None),
("Newsletter RM", None),
("Sonstiges", None),
],
),
FormField(
"Titel",
FormFieldType.TEXT,
key="titel",
required=False,
tooltip=(
"* nur wenn anrufende Person oder kontaktaufnehmende Person "
"nicht die zu beratende Person ist"
),
),
FormField(
"Anrede",
FormFieldType.TEXT,
FormFieldType.DROPDOWN,
key="anrede_anschrift",
required=True,
options=[("Sehr geehrte Frau", None), ("Sehr geehrter Herr", None)],
),
FormField(
"Name",
@@ -427,17 +430,13 @@ _INITREC_MASTER_DATA = [
"Vorname",
FormFieldType.TEXT,
key="vorname",
required=False,
required=True,
),
FormField(
"Geburtsdatum",
FormFieldType.DATE,
key="geburtsdatum",
required=False,
tooltip=(
"* Wichtig zu erfragen, da u.a. Mindestgehaltsschwelle davon abhängt "
"(Regelung bei Ü45 Jahre)"
),
),
FormField(
"Herkunftsland",
@@ -446,7 +445,6 @@ _INITREC_MASTER_DATA = [
required=True,
placeholder="Suche...",
options=COUNTRY_LIST.for_dropdown,
tooltip=("* Wichtig zu erfragen aufgrund eventueller EU-Freizügigkeitsregelung"),
),
FormField(
"Staatsangehörigkeit",
@@ -455,7 +453,6 @@ _INITREC_MASTER_DATA = [
required=False,
placeholder="Suche...",
options=COUNTRY_LIST.for_dropdown,
tooltip=("* Wichtig zu erfragen aufgrund eventueller EU-Freizügigkeitsregelung"),
),
FormField(
"Rückkehrer",
@@ -463,7 +460,6 @@ _INITREC_MASTER_DATA = [
key="rueckkehrer",
required=False,
options=[("ja", None), ("nein", None)],
tooltip=("* Wichtig zu erfragen aufgrund eventueller EU-Freizügigkeitsregelung"),
),
FormField(
"Wo befindet sich die Person?",
@@ -502,7 +498,6 @@ _INITREC_MASTER_DATA = [
key="bundesland",
required=False,
options=GERMAN_STATE_LIST.for_dropdown,
tooltip=("nur wenn Inland angegeben"),
),
FormField(
"Land",
@@ -535,13 +530,11 @@ _INITREC_MASTER_DATA = [
FormFieldType.TEXT,
key="familienstand",
required=False,
tooltip="* Wichtig zu erfragen aufgrund Lebensunterhaltssicherung",
),
FormField(
"Anzahl Kinder",
FormFieldType.DYNAMIC_DROPDOWN_NUMERIC,
required=False,
tooltip="* Wichtig zu erfragen aufgrund Lebensunterhaltssicherung",
key="anzahl_kinder",
children=[
FormField(
@@ -549,7 +542,6 @@ _INITREC_MASTER_DATA = [
FormFieldType.DROPDOWN,
required=False,
options=[(str(x), None) for x in range(11)],
tooltip="* Wichtig zu erfragen aufgrund Lebensunterhaltssicherung",
key="anzahl",
children=[
FormField("Alter Kind", FormFieldType.TEXT, key="alter"),
@@ -593,7 +585,6 @@ _INITREC_ADDITIONAL_DATA = [
("Chancenaufenthaltsrecht §104c AufenthG", None),
("Sonstiges", None),
],
tooltip="sofern nicht bekannt, unbedingt einfordern",
),
FormField(
"Gültigkeit Aufenthaltsstatus",
@@ -685,10 +676,6 @@ _INITREC_HIGHER_EDUCATION = [
FormFieldType.TEXT,
required=False,
key="HB_abschlussgrad",
tooltip=(
"bitte den Titel eingeben z.B. Doktor, Diplom oder "
"Betriebswirt (Fachschulabschluss)"
),
),
FormField(
"Abschlussgrad laut Dokument",
@@ -707,10 +694,6 @@ _INITREC_HIGHER_EDUCATION = [
FormFieldType.TEXT,
required=False,
key="HB_beruf",
tooltip=(
"bitte spezifizieren z.B. Allgemeinmedizin, Ingenieur Maschinenbau, "
"technischer Betriebswirt Datenverarbeitung"
),
),
FormField(
"Land",
@@ -737,7 +720,6 @@ _INITREC_HIGHER_EDUCATION = [
FormFieldType.TEXT,
required=False,
key="HB_bemerkungsfeld",
tooltip="z.B. Promotionen oder den Studiengang angeben",
),
]
@@ -824,7 +806,6 @@ _INITREC_WORK_EXPERIENCE = [
("Teilzeit", None),
("Sonstiges", None),
],
tooltip="Minijob, Praktikum, Wehrdienst, soziale Dienste",
),
FormField(
"Bemerkungsfeld",
@@ -889,42 +870,6 @@ _INITREC_LANGUAGES = [
INITREC_COMP = [
# FormField(
# "Ersteintrag Datum",
# FormFieldType.TEXT_DATETIME,
# required=False,
# key="Metadaten_erstellung",
# readonly=True,
# ignore_get_data=True,
# ),
# FormField(
# "Aktualisierung Datum",
# FormFieldType.TEXT_DATETIME,
# required=False,
# key="Metadaten_aktualisierung",
# readonly=True,
# ignore_get_data=True,
# ),
# FormField(
# "Aktualisierung Nutzer",
# FormFieldType.TEXT,
# required=False,
# key="Metadaten_nutzer",
# readonly=True,
# ignore_get_data=True,
# ),
# FormField(
# "Fallnummer",
# FormFieldType.TEXT,
# required=True,
# key="Grunderfassung_fallnummer",
# ),
# FormField(
# "Notizen",
# FormFieldType.LONGTEXT,
# required=False,
# key="Grunderfassung_notiz",
# ),
FormField(
"Suche",
FormFieldType.CUSTOM,
@@ -981,49 +926,6 @@ INITREC_METADATEN = [
]
INITREC_PERSON = [
# FormField(
# "Ersteintrag Datum",
# FormFieldType.TEXT_DATETIME,
# required=False,
# key="Metadaten_erstellung",
# readonly=True,
# ignore_get_data=True,
# ),
# FormField(
# "Aktualisierung Datum",
# FormFieldType.TEXT_DATETIME,
# required=False,
# key="Metadaten_aktualisierung",
# readonly=True,
# ignore_get_data=True,
# ),
# FormField(
# "Aktualisierung Nutzer",
# FormFieldType.TEXT,
# required=False,
# key="Metadaten_nutzer",
# readonly=True,
# ignore_get_data=False,
# ),
# FormField(
# "Wiedereintrittsdatum",
# FormFieldType.DATE,
# required=False,
# key="Metadaten_wiedereintrittsdatum",
# readonly=False,
# ),
# FormField(
# "Fallnummer",
# FormFieldType.TEXT,
# required=True,
# key="Grunderfassung_fallnummer",
# ),
# FormField(
# "Notizen",
# FormFieldType.LONGTEXT,
# required=False,
# key="Grunderfassung_notiz",
# ),
FormField(
"Status && Projektrelevanz",
FormFieldType.GROUP,
+8 -11
View File
@@ -1142,15 +1142,15 @@ class Grunderfassung_SuchWidget(CustomFormWidget):
self.person_search_input = cast(QComboBox, lookup[0]["widget"])
self.person_search_input.currentIndexChanged.connect(self._selected_person)
self.CHANNEL_AWARENESS_KEY = "kanal_aufmerksamkeit"
lookup = search_widgets_by_key(self.widget_registry, self.CHANNEL_AWARENESS_KEY)
self.CHANNEL_CONTACT_KEY = "kontaktweg"
lookup = search_widgets_by_key(self.widget_registry, self.CHANNEL_CONTACT_KEY)
assert len(lookup) == 1
self.channel_awareness = cast(QComboBox, lookup[0]["widget"])
self.channel_contact = cast(QComboBox, lookup[0]["widget"])
self.DATA_EXPORT_FIELDS = (
self.COMPANY_SEARCH_INPUT_KEY,
self.PERSON_SEARCH_INPUT_KEY,
self.CHANNEL_AWARENESS_KEY,
self.CHANNEL_CONTACT_KEY,
)
self.company_widgets: dict[str, QWidget] = {}
@@ -1234,7 +1234,7 @@ class Grunderfassung_SuchWidget(CustomFormWidget):
def _clear_company_fields(self) -> None:
self.person_search_input.clear()
self.channel_awareness.setCurrentIndex(0)
self.channel_contact.setCurrentIndex(0)
for widget in self.company_widgets.values():
widget = cast(QLineEdit, widget)
widget.clear()
@@ -3473,8 +3473,6 @@ class Page_InitRec(QWidget):
# TODO saving logic to connect company and person if needed
def _reset(self) -> None:
# TODO change to make these calls implicit in child modules via
# TODO staes
for form in self.STATE.child_modules:
form.reset_form()
self.STATE.ids = EntityIds()
@@ -3494,9 +3492,9 @@ class Page_InitRec(QWidget):
pers_id=5,
)
# ids = EntityIds(
# link_id=7,
# )
ids = EntityIds(
link_id=7,
)
self.STATE.ids.update(ids, ignore_none=False)
if ids.empty():
@@ -3752,7 +3750,6 @@ class Page_InitRec(QWidget):
try:
logger_page_initrec.debug("[Page -- InitRec] Call Pydantic...")
# validated_data = self.cfg.pydantic_model(**form_data)
for ent_type, state in self.STATE.initrec_form_states.items():
logger_page_initrec.debug(