Commit Graph

2 Commits

Author SHA1 Message Date
Dries Peeters ad9bfbf1ed Fix client deletion errors and add invoice validation
This commit fixes multiple issues preventing client deletion and adds proper validation to prevent deletion when invoices exist.

Database Schema Fixes:

- Migration 103: Add missing quote_number column to quotes table

  - Handles migration from offer_number to quote_number

  - Generates quote numbers for existing quotes if needed

  - Creates required unique index

- Migration 104: Add all missing columns to quotes table

  - Adds subtotal, tax_amount, visible_to_client columns

  - Adds discount fields (discount_type, discount_amount, discount_reason, coupon_code)

  - Adds payment_terms column

  - Adds approval workflow columns (approval_status, approved_by, approved_at, rejected_by, rejection_reason)

  - Creates required indexes and foreign keys

- Migration 105: Fix client_notifications foreign key cascade

  - Updates client_notifications.client_id FK to ON DELETE CASCADE

  - Updates client_notification_preferences.client_id FK to ON DELETE CASCADE

  - Prevents NOT NULL constraint violations during client deletion

Model Updates:

- Add passive_deletes=True to ClientNotification.client relationship

- Add passive_deletes=True to ClientNotificationPreferences.client relationship

- Add passive_deletes=True to ClientAttachment.client relationship

- Update ClientNote.client relationship to use passive_deletes

Route Updates:

- Add invoice validation to delete_client() and bulk_delete_clients()

- Manually delete notifications before client deletion to prevent SQLAlchemy update issues

Fixes:

- Resolves IntegrityError when deleting clients with notifications

- Resolves missing quote_number column errors

- Resolves missing quotes table columns errors

- Prevents deletion of clients with invoices (data integrity)
2026-01-05 22:07:50 +01:00
Dries Peeters 86f7946120 fix: resolve SQLAlchemy reserved word conflict in ClientNotification model
- Rename 'metadata' column to 'extra_data' in ClientNotification model
  to avoid SQLAlchemy Declarative API reserved word conflict
- Update ClientNotificationService to use 'extra_data' instead of 'metadata'
- Maintain API compatibility by returning 'metadata' key in to_dict() method
- Update migration to create 'extra_data' column instead of 'metadata'
- Improve migration idempotency and SQLite compatibility with proper checks
- Enhance backup directory handling with configurable BACKUP_FOLDER support
- Update admin routes to use centralized backup directory function

This fixes the application startup error:
  sqlalchemy.exc.InvalidRequestError: Attribute name 'metadata' is reserved
  when using the Declarative API.

The migration is now idempotent and handles both PostgreSQL and SQLite
databases safely.
2026-01-02 07:50:04 +01:00