> */ public static function genericEntityConfigs(): array { return [ 'bookings' => [ 'table' => 'bookings', 'customer_field' => 'customer_number', 'department_field' => 'department', 'search_fields' => ['id', 'customer_number', 'department', 'status', 'reference', 'notes', 'reg', 'reg_1', 'plate'], ], 'bookings_new' => [ 'table' => 'bookings_new', 'customer_field' => 'customer_number', 'department_field' => 'department', 'search_fields' => ['id', 'customer_number', 'department', 'status', 'reference', 'notes', 'reg', 'reg_1', 'plate'], ], 'branding' => ['table' => 'branding'], 'categories' => ['table' => 'categories'], 'currency_conversion_rates' => ['table' => 'currency_conversion_rates'], 'customer_codes' => ['table' => 'customer_codes'], 'customer_default_department' => [ 'table' => 'customer_default_department', 'customer_field' => 'customer_number', 'department_field' => 'department', 'search_fields' => ['id', 'customer_number', 'department', 'name', 'reference', 'description'], ], 'customer_notes' => [ 'table' => 'customer_notes', 'customer_field' => 'customer_id', 'search_fields' => ['id', 'customer_id', 'title', 'note', 'notes', 'description'], ], 'customer_vehicles_addons' => [ 'table' => 'customer_vehicles_addons', 'search_fields' => ['id', 'customer_id', 'vehicle_id', 'name', 'reference', 'description', 'type'], ], 'department_categories' => ['table' => 'department_categories', 'department_field' => 'department'], 'department_daily_reports' => [ 'table' => 'department_daily_reports', 'department_field' => 'department_id', 'search_fields' => ['id', 'department_id', 'title', 'description', 'notes', 'status'], ], 'department_gates' => ['table' => 'department_gates', 'department_field' => 'department'], 'department_goals' => ['table' => 'goals'], 'department_lanes' => ['table' => 'department_lanes', 'department_field' => 'department'], 'department_notification_sms' => ['table' => 'department_notification_sms', 'department_field' => 'department_id'], 'department_relays' => ['table' => 'department_relays', 'department_field' => 'department'], 'department_selfserve_condition_rules' => ['table' => 'department_selfserve_condition_rules'], 'department_selfserve_conditions' => ['table' => 'department_selfserve_conditions', 'department_field' => 'department'], 'department_selfserve_questions' => ['table' => 'department_selfserve_questions', 'department_field' => 'department'], 'department_selfserve_tasks' => [ 'table' => 'department_selfserve_tasks', 'department_field' => 'department', 'search_fields' => ['id', 'department', 'lane', 'product', 'task', 'description'], 'title_fields' => ['task', 'description', 'id'], 'description_fields' => ['description', 'department', 'lane', 'product'], ], 'department_selfserve_vehicle_conditions' => ['table' => 'department_selfserve_vehicle_conditions', 'customer_field' => 'customer_id', 'department_field' => 'department'], 'department_time_bookings_entries' => ['table' => 'department_time_bookings_entries', 'department_field' => 'department'], 'department_time_bookings_opening_hours' => ['table' => 'department_time_bookings_opening_hours', 'department_field' => 'department'], 'department_time_bookings_types' => ['table' => 'department_time_bookings_types', 'department_field' => 'department'], 'department_variables' => ['table' => 'department_variables'], 'fxratesapi_conversion_rates' => ['table' => 'fxratesapi_conversion_rates'], 'module_action_logs' => [ 'table' => 'module_usage_logs', 'search_fields' => ['id', 'module', 'action', 'message', 'customer_number', 'customer_id'], 'title_fields' => ['action', 'module', 'id'], 'description_fields' => ['message', 'module'], ], 'motorapi_lookups' => [ 'table' => 'motorapi_lookups', 'search_fields' => ['id', 'reg', 'plate', 'reference', 'message', 'status'], ], 'notifications' => [ 'table' => 'notifications', 'customer_field' => 'customer_number', 'search_fields' => ['id', 'customer_number', 'customer_id', 'title', 'message', 'type', 'status'], 'title_fields' => ['title', 'type', 'id'], 'description_fields' => ['message', 'status'], ], 'order_bookings' => [ 'table' => 'order_bookings', 'customer_field' => 'customer_number', 'department_field' => 'department', 'search_fields' => ['id', 'order_id', 'customer_number', 'department', 'status', 'reference', 'notes'], ], 'plate_scanners' => ['table' => 'plate_scanners', 'department_field' => 'department_id'], 'plate_scans' => [ 'table' => 'plate_scans', 'search_fields' => ['id', 'plate', 'number_plate', 'reg', 'status', 'message'], ], 'product_options' => ['table' => 'products_options', 'search_fields' => ['id', 'product_id', 'name', 'description', 'type', 'reference']], 'products' => [ 'table' => 'products', 'search_fields' => ['id', 'name', 'description', 'product_number', 'reference'], 'title_fields' => ['name', 'reference', 'id'], 'description_fields' => ['description', 'product_number'], ], 'users' => [ 'table' => 'users', 'customer_field' => 'customer_number', 'search_fields' => ['id', 'customer_number', 'display_name', 'email', 'phone', 'username', 'role'], 'title_fields' => ['display_name', 'email', 'customer_number', 'id'], 'description_fields' => ['email', 'phone', 'role'], ], 'stripe_module_customers' => [ 'table' => 'stripe_module_customers', 'customer_field' => 'customer_id', 'search_fields' => ['id', 'customer_id', 'name', 'email', 'reference', 'status'], ], 'stripe_module_orders' => [ 'table' => 'stripe_module_orders', 'customer_field' => 'customer_id', 'exclude_columns' => ['url'], 'search_fields' => ['id', 'customer_id', 'reference', 'status', 'payment_intent_id'], ], 'stripe_payment_intents' => [ 'table' => 'stripe_payment_intents', 'exclude_columns' => ['client_secret', 'data'], 'search_fields' => ['id', 'customer_id', 'status', 'reference', 'payment_method'], ], 'subuser_grants' => [ 'table' => 'subuser_grants', 'customer_field' => 'billing_customer_number', 'search_fields' => ['id', 'subuser', 'billing_customer_number', 'name', 'description', 'reference'], ], 'xlvask_customers' => [ 'table' => 'xlvask_customers', 'customer_field' => 'externId', 'customer_field_mode' => 'digits_only', ], 'xlvask_potential_order_matches' => ['table' => 'xlvask_potential_order_matches', 'customer_field' => 'customer_number', 'department_field' => 'department'], 'xlvask_usage_log_wash_items' => ['table' => 'xlvask_usage_log_wash_items'], 'xlvask_usage_logs' => ['table' => 'xlvask_usage_logs'], 'xlvask_vehicle_types' => ['table' => 'xlvask_vehicle_types'], 'xlvask_vehicles' => ['table' => 'xlvask_vehicles'], ]; } /** * @return array */ public static function allEntityTypes(): array { return array_values(array_unique([ 'objects', 'module_config', 'orders', 'order_items', 'customers', 'employees', 'subusers', 'customer_discounts', 'customer_fixed_prices', 'departments', 'permissions', 'roles', 'invoices', 'vehicles', ...array_keys(self::genericEntityConfigs()), ])); } /** * @return array */ public static function indexedEntityTypes(): array { return array_values(array_diff(self::allEntityTypes(), ['permissions', 'subusers'])); } /** * @return array */ public static function sourceTablesForEntityType(string $entityType): array { $entityType = trim(mb_strtolower($entityType)); $manual = [ 'objects' => ['object_attachments', 'orders', 'department_selfserve_tasks'], 'module_config' => ['module_config'], 'orders' => ['orders'], 'order_items' => ['order_items', 'orders'], 'customers' => ['users', system_search_economic_customer_index::TABLE], 'employees' => ['users', 'groups_permissions'], 'subusers' => ['subusers', 'subuser_grants'], 'customer_discounts' => ['price_overrides', 'users', system_search_economic_customer_index::TABLE], 'customer_fixed_prices' => ['customer_fixed_pricing', system_search_economic_customer_index::TABLE], 'departments' => ['departments'], 'permissions' => [], 'roles' => ['groups'], 'invoices' => ['collected_order_invoices'], 'vehicles' => ['customer_vehicles'], ]; if (isset($manual[$entityType])) { return $manual[$entityType]; } $config = self::genericEntityConfigs()[$entityType] ?? null; if (!is_array($config)) { return []; } $table = trim((string)($config['table'] ?? '')); return $table === '' ? [] : [$table]; } /** * @param array $tables * @return array */ public static function entityTypesForDirtyTables(array $tables): array { $normalizedTables = array_values(array_unique(array_filter(array_map( static fn($table) => is_string($table) ? trim($table, " `\t\n\r\0\x0B") : '', $tables )))); if (empty($normalizedTables)) { return []; } $types = []; foreach (self::indexedEntityTypes() as $entityType) { $sourceTables = self::sourceTablesForEntityType($entityType); if (!empty(array_intersect($normalizedTables, $sourceTables))) { $types[] = $entityType; } } return array_values(array_unique($types)); } /** * @return array> */ public static function taxonomyAliases(): array { return [ 'customers' => ['customer', 'account', 'company', 'kunde'], 'orders' => ['order', 'work order'], 'order_items' => ['order item', 'line item'], 'invoices' => ['invoice', 'billing'], 'vehicles' => ['vehicle', 'truck', 'plate'], 'employees' => ['employee', 'staff'], 'subusers' => ['subuser', 'driver'], 'customer_discounts' => ['discount', 'price override', 'rabat'], 'customer_fixed_prices' => ['fixed price', 'monthly agreement'], 'departments' => ['department', 'location'], 'permissions' => ['permission', 'acl'], 'roles' => ['role', 'group'], 'module_config' => ['module config', 'setting', 'configuration'], 'objects' => ['attachment', 'object'], 'bookings' => ['booking', 'wash booking'], 'bookings_new' => ['new booking', 'booking queue'], 'customer_notes' => ['customer note', 'note'], 'order_bookings' => ['order booking', 'scheduled order'], 'products' => ['product', 'service'], 'product_options' => ['product option', 'addon', 'add on'], 'plate_scans' => ['plate scan', 'license plate scan'], 'plate_scanners' => ['plate scanner', 'license plate scanner'], 'notifications' => ['notification', 'alert'], 'users' => ['user', 'account user'], 'module_action_logs' => ['module log', 'action log'], 'motorapi_lookups' => ['motorapi lookup', 'plate lookup'], 'xlvask_customers' => ['xlvask customer'], 'xlvask_vehicles' => ['xlvask vehicle'], 'xlvask_usage_logs' => ['xlvask usage log'], 'department_daily_reports' => ['department daily report', 'daily report'], ]; } }