@nuxt-customer-portal/invoices 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/LICENSE +21 -0
- package/README.md +4 -0
- package/app/assets/invoices.css +332 -0
- package/app/components/InvoicesAdminEmptyState.vue +28 -0
- package/app/components/InvoicesAdminInvoices.vue +950 -0
- package/app/components/InvoicesAdminListToolbar.vue +19 -0
- package/app/components/InvoicesAdminPaginatedList.vue +95 -0
- package/app/components/InvoicesClientAccessPanel.vue +63 -0
- package/app/components/InvoicesClientSettingsPanel.vue +150 -0
- package/app/components/InvoicesDashboardCard.vue +29 -0
- package/app/components/InvoicesDashboardReceivedInvoices.vue +1 -0
- package/app/components/InvoicesDashboardSalesInvoices.vue +1 -0
- package/app/components/InvoicesInvoiceDetail.vue +1109 -0
- package/app/components/InvoicesInvoiceEmailModal.vue +223 -0
- package/app/components/InvoicesPageShell.vue +7 -0
- package/app/components/InvoicesSenderDetailsForm.vue +229 -0
- package/app/composables/useInvoiceSources.ts +9 -0
- package/app/composables/useInvoices.ts +68 -0
- package/app/composables/useInvoicesAdminList.ts +113 -0
- package/app/pages/admin/invoices/[id].vue +36 -0
- package/app/pages/admin/invoices/index.vue +61 -0
- package/app/pages/admin/invoices/new.vue +18 -0
- package/app/pages/admin/invoices/settings.vue +86 -0
- package/app/pages/invoices/[id].vue +37 -0
- package/app/pages/invoices/index.vue +131 -0
- package/app/pages/invoices/viewers.vue +115 -0
- package/app/plugins/invoices-feature.ts +60 -0
- package/i18n/locales/en.json +306 -0
- package/i18n/locales/nl.json +306 -0
- package/migrations/0000_baseline.sql +235 -0
- package/migrations/meta/0000_snapshot.json +1318 -0
- package/migrations/meta/_journal.json +13 -0
- package/nuxt.config.ts +15 -0
- package/package.json +60 -0
- package/portal.manifest.mjs +9 -0
- package/server/api/invoices/admin/bootstrap.get.ts +17 -0
- package/server/api/invoices/admin/clients/[clientId]/access.get.ts +11 -0
- package/server/api/invoices/admin/clients/[clientId]/contacts/[id].delete.ts +8 -0
- package/server/api/invoices/admin/clients/[clientId]/contacts/[id].patch.ts +13 -0
- package/server/api/invoices/admin/clients/[clientId]/contacts/index.get.ts +8 -0
- package/server/api/invoices/admin/clients/[clientId]/contacts/index.post.ts +12 -0
- package/server/api/invoices/admin/email-domain.get.ts +17 -0
- package/server/api/invoices/admin/invoices/[id]/attachments/[attachmentId].delete.ts +23 -0
- package/server/api/invoices/admin/invoices/[id]/attachments/[attachmentId].get.ts +30 -0
- package/server/api/invoices/admin/invoices/[id]/attachments.post.ts +27 -0
- package/server/api/invoices/admin/invoices/[id]/email-preview.get.ts +22 -0
- package/server/api/invoices/admin/invoices/[id]/email-status.post.ts +18 -0
- package/server/api/invoices/admin/invoices/[id]/email.post.ts +24 -0
- package/server/api/invoices/admin/invoices/[id]/index.get.ts +17 -0
- package/server/api/invoices/admin/invoices/[id]/issue.post.ts +24 -0
- package/server/api/invoices/admin/invoices/[id]/payments.post.ts +24 -0
- package/server/api/invoices/admin/invoices/[id]/pdf.get.ts +29 -0
- package/server/api/invoices/admin/invoices/[id]/reminder-preview.get.ts +24 -0
- package/server/api/invoices/admin/invoices/[id]/reminder.post.ts +25 -0
- package/server/api/invoices/admin/invoices/[id].patch.ts +24 -0
- package/server/api/invoices/admin/invoices/index.get.ts +20 -0
- package/server/api/invoices/admin/invoices/index.post.ts +19 -0
- package/server/api/invoices/admin/invoices/next-number.get.ts +16 -0
- package/server/api/invoices/admin/settings.put.ts +9 -0
- package/server/api/invoices/capabilities.get.ts +25 -0
- package/server/api/invoices/client/[accessId]/viewers.get.ts +10 -0
- package/server/api/invoices/client/[accessId]/viewers.put.ts +17 -0
- package/server/api/invoices/client/invoices/[id]/attachments/[attachmentId].get.ts +20 -0
- package/server/api/invoices/client/invoices/[id]/index.get.ts +12 -0
- package/server/api/invoices/client/invoices/[id]/pdf.get.ts +23 -0
- package/server/api/invoices/client/invoices/index.get.ts +14 -0
- package/server/api/invoices/client/suppliers.get.ts +8 -0
- package/server/db/schema/invoices.ts +251 -0
- package/server/plugins/openapi-contracts.ts +55 -0
- package/server/utils/invoice-email-status.ts +64 -0
- package/server/utils/invoice-email.ts +240 -0
- package/server/utils/invoice-listing.ts +71 -0
- package/server/utils/invoice-pdf.ts +358 -0
- package/server/utils/invoice-repository.ts +821 -0
- package/server/utils/invoice-validation.ts +112 -0
- package/shared/email-delivery-status.ts +23 -0
- package/shared/feature.ts +148 -0
- package/shared/invoice-introduction.ts +21 -0
- package/shared/invoice-number.ts +24 -0
- package/shared/types/invoice.ts +251 -0
- package/tokens.css +25 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
CREATE SCHEMA "invoices";
|
|
2
|
+
--> statement-breakpoint
|
|
3
|
+
CREATE TYPE "invoices"."invoice_email_delivery_status" AS ENUM('PENDING', 'SENT', 'FAILED');--> statement-breakpoint
|
|
4
|
+
CREATE TYPE "invoices"."invoice_email_purpose" AS ENUM('INVOICE', 'REMINDER');--> statement-breakpoint
|
|
5
|
+
CREATE TYPE "invoices"."invoice_status" AS ENUM('DRAFT', 'ISSUED', 'PAID', 'VOID');--> statement-breakpoint
|
|
6
|
+
CREATE TABLE "invoices"."billing_contact" (
|
|
7
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
8
|
+
"organization_id" text NOT NULL,
|
|
9
|
+
"user_id" text,
|
|
10
|
+
"name" text NOT NULL,
|
|
11
|
+
"email" text NOT NULL,
|
|
12
|
+
"phone" text,
|
|
13
|
+
"job_title" text,
|
|
14
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
15
|
+
"updated_at" timestamp DEFAULT now() NOT NULL
|
|
16
|
+
);
|
|
17
|
+
--> statement-breakpoint
|
|
18
|
+
CREATE TABLE "invoices"."invoice" (
|
|
19
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
20
|
+
"organization_id" text NOT NULL,
|
|
21
|
+
"client_organization_id" text,
|
|
22
|
+
"number" text NOT NULL,
|
|
23
|
+
"status" "invoices"."invoice_status" DEFAULT 'DRAFT' NOT NULL,
|
|
24
|
+
"currency" text NOT NULL,
|
|
25
|
+
"issue_date" date NOT NULL,
|
|
26
|
+
"due_date" date NOT NULL,
|
|
27
|
+
"subject" text,
|
|
28
|
+
"notes" text,
|
|
29
|
+
"sender_name" text NOT NULL,
|
|
30
|
+
"sender_logo" text,
|
|
31
|
+
"sender_address" text NOT NULL,
|
|
32
|
+
"sender_registration" text,
|
|
33
|
+
"sender_vat_number" text,
|
|
34
|
+
"sender_iban" text,
|
|
35
|
+
"sender_bic" text,
|
|
36
|
+
"recipient_name" text NOT NULL,
|
|
37
|
+
"recipient_address" text NOT NULL,
|
|
38
|
+
"recipient_contact_name" text,
|
|
39
|
+
"recipient_email" text,
|
|
40
|
+
"recipient_locale" text DEFAULT 'nl' NOT NULL,
|
|
41
|
+
"created_by_id" text NOT NULL,
|
|
42
|
+
"issued_at" timestamp,
|
|
43
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
44
|
+
"updated_at" timestamp DEFAULT now() NOT NULL
|
|
45
|
+
);
|
|
46
|
+
--> statement-breakpoint
|
|
47
|
+
CREATE TABLE "invoices"."invoice_attachment" (
|
|
48
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
49
|
+
"invoice_id" text NOT NULL,
|
|
50
|
+
"file_name" text NOT NULL,
|
|
51
|
+
"content_type" text NOT NULL,
|
|
52
|
+
"size" integer NOT NULL,
|
|
53
|
+
"content_base64" text NOT NULL,
|
|
54
|
+
"uploaded_by_id" text NOT NULL,
|
|
55
|
+
"created_at" timestamp DEFAULT now() NOT NULL
|
|
56
|
+
);
|
|
57
|
+
--> statement-breakpoint
|
|
58
|
+
CREATE TABLE "invoices"."client_access" (
|
|
59
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
60
|
+
"provider_organization_id" text NOT NULL,
|
|
61
|
+
"client_organization_id" text NOT NULL,
|
|
62
|
+
"enabled" boolean DEFAULT true NOT NULL,
|
|
63
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
64
|
+
"updated_at" timestamp DEFAULT now() NOT NULL
|
|
65
|
+
);
|
|
66
|
+
--> statement-breakpoint
|
|
67
|
+
CREATE TABLE "invoices"."client_viewer" (
|
|
68
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
69
|
+
"access_id" text NOT NULL,
|
|
70
|
+
"user_id" text NOT NULL,
|
|
71
|
+
"created_by_id" text NOT NULL,
|
|
72
|
+
"created_at" timestamp DEFAULT now() NOT NULL
|
|
73
|
+
);
|
|
74
|
+
--> statement-breakpoint
|
|
75
|
+
CREATE TABLE "invoices"."invoice_email_delivery" (
|
|
76
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
77
|
+
"invoice_id" text NOT NULL,
|
|
78
|
+
"status" "invoices"."invoice_email_delivery_status" DEFAULT 'PENDING' NOT NULL,
|
|
79
|
+
"purpose" "invoices"."invoice_email_purpose" DEFAULT 'INVOICE' NOT NULL,
|
|
80
|
+
"recipient_email" text NOT NULL,
|
|
81
|
+
"cc_emails" text DEFAULT '[]' NOT NULL,
|
|
82
|
+
"locale" text NOT NULL,
|
|
83
|
+
"subject" text NOT NULL,
|
|
84
|
+
"body" text NOT NULL,
|
|
85
|
+
"actor_user_id" text NOT NULL,
|
|
86
|
+
"provider_message_id" text,
|
|
87
|
+
"provider_last_event" text,
|
|
88
|
+
"provider_status_checked_at" timestamp,
|
|
89
|
+
"error_message" text,
|
|
90
|
+
"payload_hash" text NOT NULL,
|
|
91
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
92
|
+
"updated_at" timestamp DEFAULT now() NOT NULL,
|
|
93
|
+
"sent_at" timestamp
|
|
94
|
+
);
|
|
95
|
+
--> statement-breakpoint
|
|
96
|
+
CREATE TABLE "invoices"."invoice_history" (
|
|
97
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
98
|
+
"invoice_id" text NOT NULL,
|
|
99
|
+
"action" text NOT NULL,
|
|
100
|
+
"actor_user_id" text NOT NULL,
|
|
101
|
+
"amount_minor" integer,
|
|
102
|
+
"attachment_name" text,
|
|
103
|
+
"created_at" timestamp DEFAULT now() NOT NULL
|
|
104
|
+
);
|
|
105
|
+
--> statement-breakpoint
|
|
106
|
+
CREATE TABLE "invoices"."invoice_line" (
|
|
107
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
108
|
+
"invoice_id" text NOT NULL,
|
|
109
|
+
"position" integer NOT NULL,
|
|
110
|
+
"description" text NOT NULL,
|
|
111
|
+
"quantity_milli" integer NOT NULL,
|
|
112
|
+
"unit" text DEFAULT 'item' NOT NULL,
|
|
113
|
+
"unit_price_minor" integer NOT NULL,
|
|
114
|
+
"vat_rate_basis_points" integer DEFAULT 2100 NOT NULL
|
|
115
|
+
);
|
|
116
|
+
--> statement-breakpoint
|
|
117
|
+
CREATE TABLE "invoices"."invoice_payment" (
|
|
118
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
119
|
+
"invoice_id" text NOT NULL,
|
|
120
|
+
"paid_on" date NOT NULL,
|
|
121
|
+
"amount_minor" integer NOT NULL,
|
|
122
|
+
"reference" text,
|
|
123
|
+
"note" text,
|
|
124
|
+
"created_by_id" text NOT NULL,
|
|
125
|
+
"created_at" timestamp DEFAULT now() NOT NULL
|
|
126
|
+
);
|
|
127
|
+
--> statement-breakpoint
|
|
128
|
+
CREATE TABLE "invoices"."settings" (
|
|
129
|
+
"organization_id" text PRIMARY KEY NOT NULL,
|
|
130
|
+
"enabled" boolean DEFAULT false NOT NULL,
|
|
131
|
+
"currency" text DEFAULT 'EUR' NOT NULL,
|
|
132
|
+
"default_vat_rate_basis_points" integer DEFAULT 2100 NOT NULL,
|
|
133
|
+
"address" text DEFAULT '' NOT NULL,
|
|
134
|
+
"registration_number" text,
|
|
135
|
+
"vat_number" text,
|
|
136
|
+
"iban" text,
|
|
137
|
+
"bic" text,
|
|
138
|
+
"invoice_email" text,
|
|
139
|
+
"invoice_email_template" text,
|
|
140
|
+
"preferred_locale" text DEFAULT 'nl' NOT NULL,
|
|
141
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
142
|
+
"updated_at" timestamp DEFAULT now() NOT NULL
|
|
143
|
+
);
|
|
144
|
+
--> statement-breakpoint
|
|
145
|
+
ALTER TABLE "invoices"."billing_contact" ADD CONSTRAINT "billing_contact_organization_id_organization_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organization"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
146
|
+
ALTER TABLE "invoices"."billing_contact" ADD CONSTRAINT "billing_contact_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
|
147
|
+
ALTER TABLE "invoices"."invoice" ADD CONSTRAINT "invoice_organization_id_organization_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organization"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
148
|
+
ALTER TABLE "invoices"."invoice" ADD CONSTRAINT "invoice_client_organization_id_organization_id_fk" FOREIGN KEY ("client_organization_id") REFERENCES "public"."organization"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
|
|
149
|
+
ALTER TABLE "invoices"."invoice" ADD CONSTRAINT "invoice_created_by_id_user_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "public"."user"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
|
|
150
|
+
ALTER TABLE "invoices"."invoice_attachment" ADD CONSTRAINT "invoice_attachment_invoice_id_invoice_id_fk" FOREIGN KEY ("invoice_id") REFERENCES "invoices"."invoice"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
151
|
+
ALTER TABLE "invoices"."invoice_attachment" ADD CONSTRAINT "invoice_attachment_uploaded_by_id_user_id_fk" FOREIGN KEY ("uploaded_by_id") REFERENCES "public"."user"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
|
|
152
|
+
ALTER TABLE "invoices"."client_access" ADD CONSTRAINT "client_access_provider_organization_id_organization_id_fk" FOREIGN KEY ("provider_organization_id") REFERENCES "public"."organization"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
153
|
+
ALTER TABLE "invoices"."client_access" ADD CONSTRAINT "client_access_client_organization_id_organization_id_fk" FOREIGN KEY ("client_organization_id") REFERENCES "public"."organization"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
|
|
154
|
+
ALTER TABLE "invoices"."client_viewer" ADD CONSTRAINT "client_viewer_access_id_client_access_id_fk" FOREIGN KEY ("access_id") REFERENCES "invoices"."client_access"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
155
|
+
ALTER TABLE "invoices"."client_viewer" ADD CONSTRAINT "client_viewer_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
156
|
+
ALTER TABLE "invoices"."client_viewer" ADD CONSTRAINT "client_viewer_created_by_id_user_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "public"."user"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
|
|
157
|
+
ALTER TABLE "invoices"."invoice_email_delivery" ADD CONSTRAINT "invoice_email_delivery_invoice_id_invoice_id_fk" FOREIGN KEY ("invoice_id") REFERENCES "invoices"."invoice"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
158
|
+
ALTER TABLE "invoices"."invoice_email_delivery" ADD CONSTRAINT "invoice_email_delivery_actor_user_id_user_id_fk" FOREIGN KEY ("actor_user_id") REFERENCES "public"."user"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
|
|
159
|
+
ALTER TABLE "invoices"."invoice_history" ADD CONSTRAINT "invoice_history_invoice_id_invoice_id_fk" FOREIGN KEY ("invoice_id") REFERENCES "invoices"."invoice"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
160
|
+
ALTER TABLE "invoices"."invoice_history" ADD CONSTRAINT "invoice_history_actor_user_id_user_id_fk" FOREIGN KEY ("actor_user_id") REFERENCES "public"."user"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
|
|
161
|
+
ALTER TABLE "invoices"."invoice_line" ADD CONSTRAINT "invoice_line_invoice_id_invoice_id_fk" FOREIGN KEY ("invoice_id") REFERENCES "invoices"."invoice"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
162
|
+
ALTER TABLE "invoices"."invoice_payment" ADD CONSTRAINT "invoice_payment_invoice_id_invoice_id_fk" FOREIGN KEY ("invoice_id") REFERENCES "invoices"."invoice"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
163
|
+
ALTER TABLE "invoices"."invoice_payment" ADD CONSTRAINT "invoice_payment_created_by_id_user_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "public"."user"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
|
|
164
|
+
ALTER TABLE "invoices"."settings" ADD CONSTRAINT "settings_organization_id_organization_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organization"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
165
|
+
CREATE UNIQUE INDEX "billing_contact_org_email_uidx" ON "invoices"."billing_contact" USING btree ("organization_id","email");--> statement-breakpoint
|
|
166
|
+
CREATE INDEX "billing_contact_org_idx" ON "invoices"."billing_contact" USING btree ("organization_id");--> statement-breakpoint
|
|
167
|
+
CREATE UNIQUE INDEX "invoice_org_number_uidx" ON "invoices"."invoice" USING btree ("organization_id","number");--> statement-breakpoint
|
|
168
|
+
CREATE INDEX "invoice_org_status_idx" ON "invoices"."invoice" USING btree ("organization_id","status");--> statement-breakpoint
|
|
169
|
+
CREATE INDEX "invoice_client_idx" ON "invoices"."invoice" USING btree ("client_organization_id");--> statement-breakpoint
|
|
170
|
+
CREATE INDEX "invoice_attachment_invoice_idx" ON "invoices"."invoice_attachment" USING btree ("invoice_id");--> statement-breakpoint
|
|
171
|
+
CREATE UNIQUE INDEX "invoice_client_access_provider_client_uidx" ON "invoices"."client_access" USING btree ("provider_organization_id","client_organization_id");--> statement-breakpoint
|
|
172
|
+
CREATE INDEX "invoice_client_access_client_idx" ON "invoices"."client_access" USING btree ("client_organization_id");--> statement-breakpoint
|
|
173
|
+
CREATE UNIQUE INDEX "invoice_client_viewer_access_user_uidx" ON "invoices"."client_viewer" USING btree ("access_id","user_id");--> statement-breakpoint
|
|
174
|
+
CREATE INDEX "invoice_client_viewer_user_idx" ON "invoices"."client_viewer" USING btree ("user_id");--> statement-breakpoint
|
|
175
|
+
CREATE INDEX "invoice_email_delivery_invoice_idx" ON "invoices"."invoice_email_delivery" USING btree ("invoice_id","created_at");--> statement-breakpoint
|
|
176
|
+
CREATE UNIQUE INDEX "invoice_email_delivery_pending_invoice_uidx" ON "invoices"."invoice_email_delivery" USING btree ("invoice_id") WHERE "invoices"."invoice_email_delivery"."status" = 'PENDING';--> statement-breakpoint
|
|
177
|
+
CREATE INDEX "invoice_history_invoice_idx" ON "invoices"."invoice_history" USING btree ("invoice_id");--> statement-breakpoint
|
|
178
|
+
CREATE INDEX "invoice_line_invoice_idx" ON "invoices"."invoice_line" USING btree ("invoice_id");--> statement-breakpoint
|
|
179
|
+
CREATE INDEX "invoice_payment_invoice_idx" ON "invoices"."invoice_payment" USING btree ("invoice_id");--> statement-breakpoint
|
|
180
|
+
DO $$ BEGIN
|
|
181
|
+
IF to_regclass('timesheets.workspace_settings') IS NOT NULL AND EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = 'timesheets' AND table_name = 'workspace_settings' AND column_name = 'invoicing_enabled') THEN
|
|
182
|
+
INSERT INTO invoices.settings (organization_id, enabled, currency, default_vat_rate_basis_points, address, registration_number, vat_number, iban, bic, invoice_email, invoice_email_template, preferred_locale, created_at, updated_at)
|
|
183
|
+
SELECT ws.organization_id, ws.invoicing_enabled, ws.currency, ws.default_vat_rate_basis_points, COALESCE(p.address, ''), p.registration_number, p.vat_number, p.iban, p.bic, p.invoice_email, p.invoice_email_template, COALESCE(p.preferred_locale, 'nl'), ws.created_at, ws.updated_at
|
|
184
|
+
FROM timesheets.workspace_settings ws LEFT JOIN timesheets.organization_invoice_profile p ON p.organization_id = ws.organization_id ON CONFLICT (organization_id) DO NOTHING;
|
|
185
|
+
END IF;
|
|
186
|
+
IF to_regclass('timesheets.organization_contact') IS NOT NULL THEN INSERT INTO invoices.billing_contact SELECT * FROM timesheets.organization_contact ON CONFLICT (id) DO NOTHING; END IF;
|
|
187
|
+
IF to_regclass('timesheets.workspace_client') IS NOT NULL AND EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = 'timesheets' AND table_name = 'workspace_client' AND column_name = 'invoice_access_enabled') THEN
|
|
188
|
+
INSERT INTO invoices.client_access (id, provider_organization_id, client_organization_id, enabled, created_at, updated_at) SELECT id, workspace_organization_id, client_organization_id, invoice_access_enabled, created_at, updated_at FROM timesheets.workspace_client WHERE invoice_access_enabled ON CONFLICT (id) DO NOTHING;
|
|
189
|
+
INSERT INTO clients.client_module (id, organization_id, module_id, enabled, enabled_at, created_at, updated_at) SELECT 'invoice-' || id, client_organization_id, 'invoices', true, created_at, created_at, updated_at FROM timesheets.workspace_client WHERE invoice_access_enabled ON CONFLICT (organization_id, module_id) DO UPDATE SET enabled = true, disabled_at = NULL, updated_at = EXCLUDED.updated_at;
|
|
190
|
+
END IF;
|
|
191
|
+
IF to_regclass('timesheets.workspace_client_invoice_viewer') IS NOT NULL THEN INSERT INTO invoices.client_viewer (id, access_id, user_id, created_by_id, created_at) SELECT id, workspace_client_id, user_id, created_by_id, created_at FROM timesheets.workspace_client_invoice_viewer ON CONFLICT (id) DO NOTHING; END IF;
|
|
192
|
+
IF to_regclass('timesheets.invoice') IS NOT NULL THEN
|
|
193
|
+
INSERT INTO invoices.invoice SELECT id, organization_id, client_organization_id, number, status::text::invoices.invoice_status, currency, issue_date, due_date, subject, notes, sender_name, sender_logo, sender_address, sender_registration, sender_vat_number, sender_iban, sender_bic, recipient_name, recipient_address, recipient_contact_name, recipient_email, recipient_locale, created_by_id, issued_at, created_at, updated_at FROM timesheets.invoice ON CONFLICT (id) DO NOTHING;
|
|
194
|
+
INSERT INTO invoices.invoice_line SELECT * FROM timesheets.invoice_line ON CONFLICT (id) DO NOTHING;
|
|
195
|
+
INSERT INTO invoices.invoice_payment SELECT * FROM timesheets.invoice_payment ON CONFLICT (id) DO NOTHING;
|
|
196
|
+
INSERT INTO invoices.invoice_history SELECT * FROM timesheets.invoice_history ON CONFLICT (id) DO NOTHING;
|
|
197
|
+
INSERT INTO invoices.invoice_attachment SELECT * FROM timesheets.invoice_attachment ON CONFLICT (id) DO NOTHING;
|
|
198
|
+
INSERT INTO invoices.invoice_email_delivery SELECT id, invoice_id, status::text::invoices.invoice_email_delivery_status, purpose::text::invoices.invoice_email_purpose, recipient_email, cc_emails, locale, subject, body, actor_user_id, provider_message_id, provider_last_event, provider_status_checked_at, error_message, payload_hash, created_at, updated_at, sent_at FROM timesheets.invoice_email_delivery ON CONFLICT (id) DO NOTHING;
|
|
199
|
+
|
|
200
|
+
CREATE TABLE IF NOT EXISTS invoices._legacy_timesheet_source (id text PRIMARY KEY, invoice_id text NOT NULL, invoice_line_id text NOT NULL, time_entry_id text NOT NULL);
|
|
201
|
+
INSERT INTO invoices._legacy_timesheet_source SELECT * FROM timesheets.invoice_time_entry ON CONFLICT (id) DO NOTHING;
|
|
202
|
+
|
|
203
|
+
IF EXISTS (SELECT id FROM timesheets.invoice EXCEPT SELECT id FROM invoices.invoice)
|
|
204
|
+
OR EXISTS (SELECT id FROM timesheets.invoice_line EXCEPT SELECT id FROM invoices.invoice_line)
|
|
205
|
+
OR EXISTS (SELECT id FROM timesheets.invoice_payment EXCEPT SELECT id FROM invoices.invoice_payment)
|
|
206
|
+
OR EXISTS (SELECT id FROM timesheets.invoice_history EXCEPT SELECT id FROM invoices.invoice_history)
|
|
207
|
+
OR EXISTS (SELECT id FROM timesheets.invoice_attachment EXCEPT SELECT id FROM invoices.invoice_attachment)
|
|
208
|
+
OR EXISTS (SELECT id FROM timesheets.invoice_email_delivery EXCEPT SELECT id FROM invoices.invoice_email_delivery)
|
|
209
|
+
OR EXISTS (SELECT id FROM timesheets.invoice_time_entry EXCEPT SELECT id FROM invoices._legacy_timesheet_source)
|
|
210
|
+
OR EXISTS (SELECT organization_id FROM timesheets.workspace_settings EXCEPT SELECT organization_id FROM invoices.settings)
|
|
211
|
+
OR EXISTS (SELECT id FROM timesheets.organization_contact EXCEPT SELECT id FROM invoices.billing_contact)
|
|
212
|
+
OR EXISTS (SELECT id FROM timesheets.workspace_client WHERE invoice_access_enabled EXCEPT SELECT id FROM invoices.client_access)
|
|
213
|
+
OR EXISTS (SELECT id FROM timesheets.workspace_client_invoice_viewer EXCEPT SELECT id FROM invoices.client_viewer)
|
|
214
|
+
THEN
|
|
215
|
+
RAISE EXCEPTION 'Invoice migration verification failed; legacy tables were preserved';
|
|
216
|
+
END IF;
|
|
217
|
+
|
|
218
|
+
DROP TABLE timesheets.invoice_time_entry;
|
|
219
|
+
DROP TABLE timesheets.invoice_email_delivery;
|
|
220
|
+
DROP TABLE timesheets.invoice_attachment;
|
|
221
|
+
DROP TABLE timesheets.invoice_history;
|
|
222
|
+
DROP TABLE timesheets.invoice_payment;
|
|
223
|
+
DROP TABLE timesheets.invoice_line;
|
|
224
|
+
DROP TABLE timesheets.invoice;
|
|
225
|
+
DROP TABLE IF EXISTS timesheets.workspace_client_invoice_viewer;
|
|
226
|
+
DROP TABLE IF EXISTS timesheets.organization_contact;
|
|
227
|
+
DROP TABLE IF EXISTS timesheets.organization_invoice_profile;
|
|
228
|
+
ALTER TABLE timesheets.workspace_client DROP COLUMN IF EXISTS invoice_access_enabled;
|
|
229
|
+
ALTER TABLE timesheets.workspace_settings DROP COLUMN IF EXISTS invoicing_enabled;
|
|
230
|
+
ALTER TABLE timesheets.workspace_settings DROP COLUMN IF EXISTS default_vat_rate_basis_points;
|
|
231
|
+
DROP TYPE IF EXISTS timesheets.invoice_email_purpose;
|
|
232
|
+
DROP TYPE IF EXISTS timesheets.invoice_email_delivery_status;
|
|
233
|
+
DROP TYPE IF EXISTS timesheets.invoice_status;
|
|
234
|
+
END IF;
|
|
235
|
+
END $$;
|