From 30d761f899c0c9b83440e211e79db52a922e58c6 Mon Sep 17 00:00:00 2001 From: florianfederspiel Date: Sat, 21 Feb 2026 21:21:27 +0100 Subject: [PATCH] fix memberrlation --- .../0016_fix_memberrelation_column_usage.sql | 33 ++++++ backend/db/migrations/0017_slow_the_hood.sql | 108 ++++++++++++++++++ backend/db/migrations/meta/_journal.json | 16 ++- backend/db/schema/customers.ts | 2 + .../columnRenderings/memberrelation.vue | 8 +- frontend/stores/data.js | 2 +- 6 files changed, 165 insertions(+), 4 deletions(-) create mode 100644 backend/db/migrations/0016_fix_memberrelation_column_usage.sql create mode 100644 backend/db/migrations/0017_slow_the_hood.sql diff --git a/backend/db/migrations/0016_fix_memberrelation_column_usage.sql b/backend/db/migrations/0016_fix_memberrelation_column_usage.sql new file mode 100644 index 0000000..25562a5 --- /dev/null +++ b/backend/db/migrations/0016_fix_memberrelation_column_usage.sql @@ -0,0 +1,33 @@ +ALTER TABLE "customers" ADD COLUMN IF NOT EXISTS "memberrelation" bigint; + +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM pg_constraint + WHERE conname = 'customers_memberrelation_memberrelations_id_fk' + ) THEN + ALTER TABLE "customers" + ADD CONSTRAINT "customers_memberrelation_memberrelations_id_fk" + FOREIGN KEY ("memberrelation") + REFERENCES "public"."memberrelations"("id") + ON DELETE no action + ON UPDATE no action; + END IF; +END $$; + +UPDATE "customers" +SET "memberrelation" = ("infoData"->>'memberrelation')::bigint +WHERE + "memberrelation" IS NULL + AND "type" = 'Mitglied' + AND jsonb_typeof(COALESCE("infoData", '{}'::jsonb)) = 'object' + AND COALESCE("infoData", '{}'::jsonb) ? 'memberrelation' + AND ("infoData"->>'memberrelation') ~ '^[0-9]+$'; + +UPDATE "customers" +SET "infoData" = COALESCE("infoData", '{}'::jsonb) - 'memberrelation' +WHERE + "type" = 'Mitglied' + AND jsonb_typeof(COALESCE("infoData", '{}'::jsonb)) = 'object' + AND COALESCE("infoData", '{}'::jsonb) ? 'memberrelation'; diff --git a/backend/db/migrations/0017_slow_the_hood.sql b/backend/db/migrations/0017_slow_the_hood.sql new file mode 100644 index 0000000..9d3dbd7 --- /dev/null +++ b/backend/db/migrations/0017_slow_the_hood.sql @@ -0,0 +1,108 @@ +CREATE TABLE "contracttypes" ( + "id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (sequence name "contracttypes_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1), + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "tenant" bigint NOT NULL, + "name" text NOT NULL, + "description" text, + "paymentType" text, + "recurring" boolean DEFAULT false NOT NULL, + "billingInterval" text, + "archived" boolean DEFAULT false NOT NULL, + "updated_at" timestamp with time zone, + "updated_by" uuid +); +--> statement-breakpoint +CREATE TABLE "customerinventoryitems" ( + "id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (sequence name "customerinventoryitems_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1), + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "name" text NOT NULL, + "description" text, + "tenant" bigint NOT NULL, + "customer" bigint NOT NULL, + "customerspace" bigint, + "customerInventoryId" text NOT NULL, + "serialNumber" text, + "quantity" bigint DEFAULT 0 NOT NULL, + "manufacturer" text, + "manufacturerNumber" text, + "purchaseDate" date, + "purchasePrice" double precision DEFAULT 0, + "currentValue" double precision, + "product" bigint, + "vendor" bigint, + "archived" boolean DEFAULT false NOT NULL, + "updated_at" timestamp with time zone, + "updated_by" uuid +); +--> statement-breakpoint +CREATE TABLE "customerspaces" ( + "id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (sequence name "customerspaces_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1), + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "name" text NOT NULL, + "type" text NOT NULL, + "tenant" bigint NOT NULL, + "customer" bigint NOT NULL, + "spaceNumber" text NOT NULL, + "parentSpace" bigint, + "infoData" jsonb DEFAULT '{"zip":"","city":"","streetNumber":""}'::jsonb NOT NULL, + "description" text, + "archived" boolean DEFAULT false NOT NULL, + "updated_at" timestamp with time zone, + "updated_by" uuid +); +--> statement-breakpoint +CREATE TABLE "entitybankaccounts" ( + "id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (sequence name "entitybankaccounts_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1), + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "tenant" bigint NOT NULL, + "iban_encrypted" jsonb NOT NULL, + "bic_encrypted" jsonb NOT NULL, + "bank_name_encrypted" jsonb NOT NULL, + "description" text, + "updated_at" timestamp with time zone, + "updated_by" uuid, + "archived" boolean DEFAULT false NOT NULL +); +--> statement-breakpoint +CREATE TABLE "memberrelations" ( + "id" bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (sequence name "memberrelations_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1), + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "tenant" bigint NOT NULL, + "type" text NOT NULL, + "billingInterval" text NOT NULL, + "billingAmount" double precision DEFAULT 0 NOT NULL, + "archived" boolean DEFAULT false NOT NULL, + "updated_at" timestamp with time zone, + "updated_by" uuid +); +--> statement-breakpoint +ALTER TABLE "tenants" ALTER COLUMN "numberRanges" SET DEFAULT '{"vendors":{"prefix":"","suffix":"","nextNumber":10000},"customers":{"prefix":"","suffix":"","nextNumber":10000},"products":{"prefix":"AT-","suffix":"","nextNumber":1000},"quotes":{"prefix":"AN-","suffix":"","nextNumber":1000},"confirmationOrders":{"prefix":"AB-","suffix":"","nextNumber":1000},"invoices":{"prefix":"RE-","suffix":"","nextNumber":1000},"spaces":{"prefix":"LP-","suffix":"","nextNumber":1000},"customerspaces":{"prefix":"KLP-","suffix":"","nextNumber":1000},"inventoryitems":{"prefix":"IA-","suffix":"","nextNumber":1000},"customerinventoryitems":{"prefix":"KIA-","suffix":"","nextNumber":1000},"projects":{"prefix":"PRJ-","suffix":"","nextNumber":1000},"costcentres":{"prefix":"KST-","suffix":"","nextNumber":1000}}'::jsonb;--> statement-breakpoint +ALTER TABLE "contracts" ADD COLUMN "contracttype" bigint;--> statement-breakpoint +ALTER TABLE "contracts" ADD COLUMN "billingInterval" text;--> statement-breakpoint +ALTER TABLE "customers" ADD COLUMN "customTaxType" text;--> statement-breakpoint +ALTER TABLE "customers" ADD COLUMN "memberrelation" bigint;--> statement-breakpoint +ALTER TABLE "historyitems" ADD COLUMN "customerspace" bigint;--> statement-breakpoint +ALTER TABLE "historyitems" ADD COLUMN "customerinventoryitem" bigint;--> statement-breakpoint +ALTER TABLE "historyitems" ADD COLUMN "memberrelation" bigint;--> statement-breakpoint +ALTER TABLE "services" ADD COLUMN "priceUpdateLocked" boolean DEFAULT false NOT NULL;--> statement-breakpoint +ALTER TABLE "contracttypes" ADD CONSTRAINT "contracttypes_tenant_tenants_id_fk" FOREIGN KEY ("tenant") REFERENCES "public"."tenants"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "contracttypes" ADD CONSTRAINT "contracttypes_updated_by_auth_users_id_fk" FOREIGN KEY ("updated_by") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "customerinventoryitems" ADD CONSTRAINT "customerinventoryitems_tenant_tenants_id_fk" FOREIGN KEY ("tenant") REFERENCES "public"."tenants"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "customerinventoryitems" ADD CONSTRAINT "customerinventoryitems_customer_customers_id_fk" FOREIGN KEY ("customer") REFERENCES "public"."customers"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "customerinventoryitems" ADD CONSTRAINT "customerinventoryitems_customerspace_customerspaces_id_fk" FOREIGN KEY ("customerspace") REFERENCES "public"."customerspaces"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "customerinventoryitems" ADD CONSTRAINT "customerinventoryitems_product_products_id_fk" FOREIGN KEY ("product") REFERENCES "public"."products"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "customerinventoryitems" ADD CONSTRAINT "customerinventoryitems_vendor_vendors_id_fk" FOREIGN KEY ("vendor") REFERENCES "public"."vendors"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "customerinventoryitems" ADD CONSTRAINT "customerinventoryitems_updated_by_auth_users_id_fk" FOREIGN KEY ("updated_by") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "customerspaces" ADD CONSTRAINT "customerspaces_tenant_tenants_id_fk" FOREIGN KEY ("tenant") REFERENCES "public"."tenants"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "customerspaces" ADD CONSTRAINT "customerspaces_customer_customers_id_fk" FOREIGN KEY ("customer") REFERENCES "public"."customers"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "customerspaces" ADD CONSTRAINT "customerspaces_parentSpace_customerspaces_id_fk" FOREIGN KEY ("parentSpace") REFERENCES "public"."customerspaces"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "customerspaces" ADD CONSTRAINT "customerspaces_updated_by_auth_users_id_fk" FOREIGN KEY ("updated_by") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "entitybankaccounts" ADD CONSTRAINT "entitybankaccounts_tenant_tenants_id_fk" FOREIGN KEY ("tenant") REFERENCES "public"."tenants"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "entitybankaccounts" ADD CONSTRAINT "entitybankaccounts_updated_by_auth_users_id_fk" FOREIGN KEY ("updated_by") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "memberrelations" ADD CONSTRAINT "memberrelations_tenant_tenants_id_fk" FOREIGN KEY ("tenant") REFERENCES "public"."tenants"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "memberrelations" ADD CONSTRAINT "memberrelations_updated_by_auth_users_id_fk" FOREIGN KEY ("updated_by") REFERENCES "public"."auth_users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "contracts" ADD CONSTRAINT "contracts_contracttype_contracttypes_id_fk" FOREIGN KEY ("contracttype") REFERENCES "public"."contracttypes"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "customers" ADD CONSTRAINT "customers_memberrelation_memberrelations_id_fk" FOREIGN KEY ("memberrelation") REFERENCES "public"."memberrelations"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "historyitems" ADD CONSTRAINT "historyitems_customerspace_customerspaces_id_fk" FOREIGN KEY ("customerspace") REFERENCES "public"."customerspaces"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "historyitems" ADD CONSTRAINT "historyitems_customerinventoryitem_customerinventoryitems_id_fk" FOREIGN KEY ("customerinventoryitem") REFERENCES "public"."customerinventoryitems"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "historyitems" ADD CONSTRAINT "historyitems_memberrelation_memberrelations_id_fk" FOREIGN KEY ("memberrelation") REFERENCES "public"."memberrelations"("id") ON DELETE no action ON UPDATE no action; \ No newline at end of file diff --git a/backend/db/migrations/meta/_journal.json b/backend/db/migrations/meta/_journal.json index 643601e..a9dd05f 100644 --- a/backend/db/migrations/meta/_journal.json +++ b/backend/db/migrations/meta/_journal.json @@ -113,6 +113,20 @@ "when": 1773000700000, "tag": "0015_wise_memberrelation_history", "breakpoints": true + }, + { + "idx": 16, + "version": "7", + "when": 1773000800000, + "tag": "0016_fix_memberrelation_column_usage", + "breakpoints": true + }, + { + "idx": 17, + "version": "7", + "when": 1771704862789, + "tag": "0017_slow_the_hood", + "breakpoints": true } ] -} +} \ No newline at end of file diff --git a/backend/db/schema/customers.ts b/backend/db/schema/customers.ts index 653d27f..c720d69 100644 --- a/backend/db/schema/customers.ts +++ b/backend/db/schema/customers.ts @@ -10,6 +10,7 @@ import { } from "drizzle-orm/pg-core" import { tenants } from "./tenants" import { authUsers } from "./auth_users" +import { memberrelations } from "./memberrelations" export const customers = pgTable( "customers", @@ -63,6 +64,7 @@ export const customers = pgTable( customPaymentType: text("custom_payment_type"), // ENUM payment_types separat? customTaxType: text("customTaxType"), + memberrelation: bigint("memberrelation", { mode: "number" }).references(() => memberrelations.id), } ) diff --git a/frontend/components/columnRenderings/memberrelation.vue b/frontend/components/columnRenderings/memberrelation.vue index e126093..95c0edd 100644 --- a/frontend/components/columnRenderings/memberrelation.vue +++ b/frontend/components/columnRenderings/memberrelation.vue @@ -11,18 +11,22 @@ const relations = ref([]) const normalizeId = (value) => { if (value === null || value === undefined || value === "") return null + if (typeof value === "object") return normalizeId(value.id) const parsed = Number(value) return Number.isNaN(parsed) ? String(value) : parsed } const relationLabel = computed(() => { - const id = normalizeId(props.row?.infoData?.memberrelation) + const relation = props.row?.memberrelation + if (relation && typeof relation === "object" && relation.type) return relation.type + + const id = normalizeId(relation) if (!id) return "" return relations.value.find((i) => normalizeId(i.id) === id)?.type || "" }) const relationId = computed(() => { - return normalizeId(props.row?.infoData?.memberrelation) + return normalizeId(props.row?.memberrelation) }) const loadRelations = async () => { diff --git a/frontend/stores/data.js b/frontend/stores/data.js index 99dbeae..adf4f52 100644 --- a/frontend/stores/data.js +++ b/frontend/stores/data.js @@ -535,7 +535,7 @@ export const useDataStore = defineStore('data', () => { disabledInTable: true }, { - key: "infoData.memberrelation", + key: "memberrelation", label: "MitgliedsverhÃĪltnis", component: memberrelation, inputType: "select",