fix: Store service prices in cents and fix contracts permission

- Update Service model to use price_cents/deposit_amount_cents as IntegerField
- Add @property methods for backward compatibility (price, deposit_amount return dollars)
- Update ServiceSerializer to convert dollars <-> cents on read/write
- Add migration to convert column types from numeric to integer
- Fix BusinessEditModal to properly use typed PlatformBusiness interface
- Add missing feature permission fields to PlatformBusiness TypeScript interface

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
poduck
2025-12-10 03:37:13 -05:00
parent 30ec150d90
commit 18c9a69d75
5 changed files with 138 additions and 43 deletions

View File

@@ -33,6 +33,24 @@ export interface PlatformBusiness {
can_use_custom_domain: boolean;
can_white_label: boolean;
can_api_access: boolean;
// Feature permissions (optional - returned by API but may not always be present in tests)
can_add_video_conferencing?: boolean;
can_connect_to_api?: boolean;
can_book_repeated_events?: boolean;
can_require_2fa?: boolean;
can_download_logs?: boolean;
can_delete_data?: boolean;
can_use_sms_reminders?: boolean;
can_use_masked_phone_numbers?: boolean;
can_use_pos?: boolean;
can_use_mobile_app?: boolean;
can_export_data?: boolean;
can_use_plugins?: boolean;
can_use_tasks?: boolean;
can_create_plugins?: boolean;
can_use_webhooks?: boolean;
can_use_calendar_sync?: boolean;
can_use_contracts?: boolean;
}
export interface PlatformBusinessUpdate {

View File

@@ -194,7 +194,6 @@ const BusinessEditModal: React.FC<BusinessEditModalProps> = ({ business, isOpen,
// Update form when business changes
useEffect(() => {
if (business) {
const b = business as any;
setEditForm({
name: business.name,
is_active: business.is_active,
@@ -204,36 +203,38 @@ const BusinessEditModal: React.FC<BusinessEditModalProps> = ({ business, isOpen,
max_resources: business.max_resources || 10,
// Platform Permissions (flat, matching backend)
can_manage_oauth_credentials: business.can_manage_oauth_credentials || false,
can_accept_payments: b.can_accept_payments || false,
can_use_custom_domain: b.can_use_custom_domain || false,
can_white_label: b.can_white_label || false,
can_api_access: b.can_api_access || false,
can_accept_payments: business.can_accept_payments || false,
can_use_custom_domain: business.can_use_custom_domain || false,
can_white_label: business.can_white_label || false,
can_api_access: business.can_api_access || false,
// Feature permissions (flat, matching backend)
can_add_video_conferencing: b.can_add_video_conferencing || false,
can_connect_to_api: b.can_connect_to_api || false,
can_book_repeated_events: b.can_book_repeated_events ?? true,
can_require_2fa: b.can_require_2fa || false,
can_download_logs: b.can_download_logs || false,
can_delete_data: b.can_delete_data || false,
can_use_sms_reminders: b.can_use_sms_reminders || false,
can_use_masked_phone_numbers: b.can_use_masked_phone_numbers || false,
can_use_pos: b.can_use_pos || false,
can_use_mobile_app: b.can_use_mobile_app || false,
can_export_data: b.can_export_data || false,
can_use_plugins: b.can_use_plugins ?? true,
can_use_tasks: b.can_use_tasks ?? true,
can_create_plugins: b.can_create_plugins || false,
can_use_webhooks: b.can_use_webhooks || false,
can_use_calendar_sync: b.can_use_calendar_sync || false,
can_use_contracts: b.can_use_contracts || false,
can_process_refunds: b.can_process_refunds || false,
can_create_packages: b.can_create_packages || false,
can_use_email_templates: b.can_use_email_templates || false,
can_customize_booking_page: b.can_customize_booking_page || false,
advanced_reporting: b.advanced_reporting || false,
priority_support: b.priority_support || false,
dedicated_support: b.dedicated_support || false,
sso_enabled: b.sso_enabled || false,
can_add_video_conferencing: business.can_add_video_conferencing || false,
can_connect_to_api: business.can_connect_to_api || false,
can_book_repeated_events: business.can_book_repeated_events ?? true,
can_require_2fa: business.can_require_2fa || false,
can_download_logs: business.can_download_logs || false,
can_delete_data: business.can_delete_data || false,
can_use_sms_reminders: business.can_use_sms_reminders || false,
can_use_masked_phone_numbers: business.can_use_masked_phone_numbers || false,
can_use_pos: business.can_use_pos || false,
can_use_mobile_app: business.can_use_mobile_app || false,
can_export_data: business.can_export_data || false,
can_use_plugins: business.can_use_plugins ?? true,
can_use_tasks: business.can_use_tasks ?? true,
can_create_plugins: business.can_create_plugins || false,
can_use_webhooks: business.can_use_webhooks || false,
can_use_calendar_sync: business.can_use_calendar_sync || false,
can_use_contracts: business.can_use_contracts || false,
// Note: These fields are in the form but not yet on the backend model
// They will be ignored by the backend serializer until added to the Tenant model
can_process_refunds: false,
can_create_packages: false,
can_use_email_templates: false,
can_customize_booking_page: false,
advanced_reporting: false,
priority_support: false,
dedicated_support: false,
sso_enabled: false,
});
}
}, [business]);