# SaveAdHocFieldDefinitionEventType - Advanced Documentation ## Overview Creates or updates a single calendar event type ad hoc field definition, including its dropdown options, role-based view/edit permissions, and the list of calendar event types the field applies to. The caller passes one field definition object per call. This is a long-running operation - it declares a `[LongRunningId] string ProcessID` parameter and is invoked through `ProcessStatus.Run`. The definition is saved and committed and the operation returns; there is no dependent widget or form regeneration step of any kind. `IsSynced` is not used for this field type and is not set anywhere in the save. ## Business Rules - The field definition is validated before any write: field label is required, must be a valid field name (cannot contain `,`, `"`, `#`), data type is required, and category is required (`ValidateFieldDefinition`) - The field label must be unique for the company within `vwAdHocFieldDefinitionsEventTypes` only; the uniqueness check is scoped to this company's event type ad hoc fields and does not consult any other field-type view - New field definitions (`Item.ID < 1`) are assigned the next sort order, computed from the count of existing field-label rows found during the uniqueness check - Dropdown options, edit roles, view roles, and the used-by calendar event type list are synced as Aptify sub-types (`AdHocFieldDefinitionsEventTypeDropdownOptions`, `AdHocFieldDefinitionsEventTypeEditRoles`, `AdHocFieldDefinitionsEventTypeViewRoles`, `AdHocFieldDefinitionsEventTypeUsedBy`) - existing rows not present in the incoming lists are removed, and missing rows are added - `Item.UsedBy` (calendar event type IDs) is synced into `AdHocFieldDefinitionsEventTypeUsedBy` as a plain list of associations; nothing in this operation reads `Item.UsedBy` back to drive any further work - There is no pre-save widget-field recalculation step for this operation - There is no post-save dependent-widget or generated-form regeneration step for this operation at all - the method ends after the save, commit, and cache clear - The ad hoc field cache for event type fields is cleared exactly once, immediately after commit (`ClearAdHocCache(AdHocFieldType.Event, CompanyID)`) - The operation reports a single progress message (`ProcessStatus.SetProcessStatus(ProcessID, "Saving Field [{FieldLabel}]")`) before the uniqueness check runs; no further progress is reported afterward ## Permissions & Security - Caller must be logged in (`curPerson.ID >= 1`) - Caller must have a company selected (`curCompany.ID >= 1`) - Caller must be a member of the current company (`IsPartOfCompany` check) - Caller must have the **ManageFirm** permission, checked inside the controller method (`Controllers.Role.Permissions.ManageFirm`) - The saved field definition is always scoped to the caller's current company (`CompanyID` is set from `_UnitOfWork.CurrentCompany.ID`, not from the incoming `Item`) ## Data Flow 1. Validate authentication, company membership, and ManageFirm permission (in the service method, before the controller is invoked) 2. Validate the field definition shape (`ValidateFieldDefinition`) 3. Report progress: "Saving Field [{FieldLabel}]" 4. Query `vwAdHocFieldDefinitionsEventTypes` for an existing field label match for this company; throw if found 5. Get (or create) the `AdHocFieldDefinitionsEventTypes` Aptify entity object for `Item.ID` and set its scalar fields (`CompanyID`, `FieldLabel`, `DataType`, `CategoryID`, `Format`, `Description`, `IsReadOnly`) 6. If this is a new field (`ID < 1`), assign the computed sort order 7. Sync the edit role, view role, dropdown option, and used-by calendar event type sub-types 8. Begin transaction 9. Save the entity object; throw if the save fails 10. Commit transaction 11. Set `Item.ID` to the saved record's ID 12. Clear the ad hoc field cache for `Event` fields 13. Return the saved `Item` ## Side Effects - **Database write**: The `AdHocFieldDefinitionsEventTypes` entity record is created or updated via Aptify - **Database writes**: Dropdown option, edit role, view role, and used-by calendar event type sub-type rows are synced (added/removed) to match the incoming definition - **Cache invalidation**: Ad hoc field cache for `Event` fields is cleared once, immediately after commit ## Error Conditions - `RadoloException("You must be logged in to perform this action.")` - caller not authenticated - `RadoloException("You must have a company selected to perform this action.")` - no company context - `RadoloException("You can only perform this action for a company you are a member of.")` - cross-company attempt - `RadoloException("You do not have permission to save event type adhoc fields. Please contact your administrator.")` - missing ManageFirm permission - `RadoloException("Field Label is required.")` - missing field label - `RadoloException("Field Label can not contain ',\",#.")` - invalid field label characters - `RadoloException("Data Type is required.")` - missing data type - `RadoloException("Category is required.")` - missing or invalid category - `RadoloException("An ad hoc field with this field label[{FieldLabel}] already exists.")` - duplicate field label within event type ad hoc fields - `RadoloException("There was a problem saving this ad hoc field definition : {error}")` - Aptify entity save failed - The method has no try/catch of its own; any exception raised during the save propagates to the caller unmodified ## Usage Notes - This is a long-running operation wrapped in `ProcessStatus.Run` with a `[LongRunningId]` `ProcessID` parameter, and it does report one progress message before the duplicate-label check, unlike some sibling save operations that report none. - This operation performs no dependent-widget search and no generated-form regeneration of any kind - a caller does not need to account for any background or best-effort work continuing after the response is returned. - The incoming `Item.CompanyID` is not trusted; the field is always saved under the caller's current company. - `IsSynced` is not read or set anywhere in this operation and has no effect on event type ad hoc fields.