diff --git a/_ide_helper_models.php b/_ide_helper_models.php index 8414883ba6..1e43672ec5 100644 --- a/_ide_helper_models.php +++ b/_ide_helper_models.php @@ -330,6 +330,8 @@ class IdeHelperSystemUser {} * @property-read \Illuminate\Database\Eloquent\Collection $events * @property-read int|null $events_count * @property-read mixed $is_admin + * @property-read \Illuminate\Database\Eloquent\Collection $licenses + * @property-read int|null $licenses_count * @property-read \Spatie\MediaLibrary\MediaCollections\Models\Collections\MediaCollection $media * @property-read int|null $media_count * @property-read \Illuminate\Notifications\DatabaseNotificationCollection $notifications @@ -820,6 +822,37 @@ class IdeHelperAssistantChatMessageLog {} class IdeHelperAudit {} } +namespace AdvisingApp\Authorization\Models{ +/** + * AdvisingApp\Authorization\Models\License + * + * @property string $id + * @property string $user_id + * @property \AdvisingApp\Authorization\Enums\LicenseType $type + * @property \Illuminate\Support\Carbon|null $created_at + * @property \Illuminate\Support\Carbon|null $updated_at + * @property \Illuminate\Support\Carbon|null $deleted_at + * @property-read \Illuminate\Database\Eloquent\Collection $audits + * @property-read int|null $audits_count + * @property-read \App\Models\User $user + * @method static \Illuminate\Database\Eloquent\Builder|License newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|License newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|License onlyTrashed() + * @method static \Illuminate\Database\Eloquent\Builder|License query() + * @method static \Illuminate\Database\Eloquent\Builder|License whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|License whereDeletedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|License whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|License whereType($value) + * @method static \Illuminate\Database\Eloquent\Builder|License whereUpdatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|License whereUserId($value) + * @method static \Illuminate\Database\Eloquent\Builder|License withTrashed() + * @method static \Illuminate\Database\Eloquent\Builder|License withoutTrashed() + * @mixin \Eloquent + */ + #[\AllowDynamicProperties] + class IdeHelperLicense {} +} + namespace AdvisingApp\Authorization\Models{ /** * AdvisingApp\Authorization\Models\Permission @@ -1011,7 +1044,7 @@ class IdeHelperCampaign {} * @property string $campaign_id * @property \AdvisingApp\Campaign\Enums\CampaignActionType $type * @property array $data - * @property string $execute_at + * @property \Illuminate\Support\Carbon $execute_at * @property string|null $last_execution_attempt_at * @property string|null $last_execution_attempt_error * @property string|null $successfully_executed_at @@ -1311,6 +1344,7 @@ class IdeHelperEmailTemplate {} * @method static \AdvisingApp\Engagement\Database\Factories\EngagementFactory factory($count = null, $state = []) * @method static \Illuminate\Database\Eloquent\Builder|Engagement hasBeenDelivered() * @method static \Illuminate\Database\Eloquent\Builder|Engagement hasNotBeenDelivered() + * @method static \Illuminate\Database\Eloquent\Builder|Engagement isAwaitingDelivery() * @method static \Illuminate\Database\Eloquent\Builder|Engagement isNotPartOfABatch() * @method static \Illuminate\Database\Eloquent\Builder|Engagement isScheduled() * @method static \Illuminate\Database\Eloquent\Builder|Engagement newModelQuery() @@ -1984,6 +2018,189 @@ class IdeHelperInteractionStatus {} class IdeHelperInteractionType {} } +namespace AdvisingApp\InventoryManagement\Models{ +/** + * AdvisingApp\InventoryManagement\Models\Asset + * + * @property string $id + * @property string $serial_number + * @property string $name + * @property string $description + * @property string $type_id + * @property string $status_id + * @property string $location_id + * @property string $purchase_date + * @property \Illuminate\Support\Carbon|null $created_at + * @property \Illuminate\Support\Carbon|null $updated_at + * @property-read \Illuminate\Database\Eloquent\Collection $audits + * @property-read int|null $audits_count + * @property-read \AdvisingApp\InventoryManagement\Models\AssetLocation $location + * @property-read \Illuminate\Database\Eloquent\Collection $maintenanceActivities + * @property-read int|null $maintenance_activities_count + * @property-read \AdvisingApp\InventoryManagement\Models\AssetStatus $status + * @property-read \AdvisingApp\InventoryManagement\Models\AssetType $type + * @method static \AdvisingApp\InventoryManagement\Database\Factories\AssetFactory factory($count = null, $state = []) + * @method static \Illuminate\Database\Eloquent\Builder|Asset newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|Asset newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|Asset query() + * @method static \Illuminate\Database\Eloquent\Builder|Asset whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|Asset whereDescription($value) + * @method static \Illuminate\Database\Eloquent\Builder|Asset whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|Asset whereLocationId($value) + * @method static \Illuminate\Database\Eloquent\Builder|Asset whereName($value) + * @method static \Illuminate\Database\Eloquent\Builder|Asset wherePurchaseDate($value) + * @method static \Illuminate\Database\Eloquent\Builder|Asset whereSerialNumber($value) + * @method static \Illuminate\Database\Eloquent\Builder|Asset whereStatusId($value) + * @method static \Illuminate\Database\Eloquent\Builder|Asset whereTypeId($value) + * @method static \Illuminate\Database\Eloquent\Builder|Asset whereUpdatedAt($value) + * @mixin \Eloquent + */ + #[\AllowDynamicProperties] + class IdeHelperAsset {} +} + +namespace AdvisingApp\InventoryManagement\Models{ +/** + * AdvisingApp\InventoryManagement\Models\AssetLocation + * + * @property string $id + * @property string $name + * @property \Illuminate\Support\Carbon|null $created_at + * @property \Illuminate\Support\Carbon|null $updated_at + * @property-read \Illuminate\Database\Eloquent\Collection $assets + * @property-read int|null $assets_count + * @property-read \Illuminate\Database\Eloquent\Collection $audits + * @property-read int|null $audits_count + * @method static \AdvisingApp\InventoryManagement\Database\Factories\AssetLocationFactory factory($count = null, $state = []) + * @method static \Illuminate\Database\Eloquent\Builder|AssetLocation newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|AssetLocation newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|AssetLocation query() + * @method static \Illuminate\Database\Eloquent\Builder|AssetLocation whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|AssetLocation whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|AssetLocation whereName($value) + * @method static \Illuminate\Database\Eloquent\Builder|AssetLocation whereUpdatedAt($value) + * @mixin \Eloquent + */ + #[\AllowDynamicProperties] + class IdeHelperAssetLocation {} +} + +namespace AdvisingApp\InventoryManagement\Models{ +/** + * AdvisingApp\InventoryManagement\Models\AssetStatus + * + * @property string $id + * @property string $name + * @property \Illuminate\Support\Carbon|null $created_at + * @property \Illuminate\Support\Carbon|null $updated_at + * @property-read \Illuminate\Database\Eloquent\Collection $assets + * @property-read int|null $assets_count + * @property-read \Illuminate\Database\Eloquent\Collection $audits + * @property-read int|null $audits_count + * @method static \AdvisingApp\InventoryManagement\Database\Factories\AssetStatusFactory factory($count = null, $state = []) + * @method static \Illuminate\Database\Eloquent\Builder|AssetStatus newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|AssetStatus newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|AssetStatus query() + * @method static \Illuminate\Database\Eloquent\Builder|AssetStatus whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|AssetStatus whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|AssetStatus whereName($value) + * @method static \Illuminate\Database\Eloquent\Builder|AssetStatus whereUpdatedAt($value) + * @mixin \Eloquent + */ + #[\AllowDynamicProperties] + class IdeHelperAssetStatus {} +} + +namespace AdvisingApp\InventoryManagement\Models{ +/** + * AdvisingApp\InventoryManagement\Models\AssetType + * + * @property string $id + * @property string $name + * @property \Illuminate\Support\Carbon|null $created_at + * @property \Illuminate\Support\Carbon|null $updated_at + * @property-read \Illuminate\Database\Eloquent\Collection $assets + * @property-read int|null $assets_count + * @property-read \Illuminate\Database\Eloquent\Collection $audits + * @property-read int|null $audits_count + * @method static \AdvisingApp\InventoryManagement\Database\Factories\AssetTypeFactory factory($count = null, $state = []) + * @method static \Illuminate\Database\Eloquent\Builder|AssetType newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|AssetType newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|AssetType query() + * @method static \Illuminate\Database\Eloquent\Builder|AssetType whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|AssetType whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|AssetType whereName($value) + * @method static \Illuminate\Database\Eloquent\Builder|AssetType whereUpdatedAt($value) + * @mixin \Eloquent + */ + #[\AllowDynamicProperties] + class IdeHelperAssetType {} +} + +namespace AdvisingApp\InventoryManagement\Models{ +/** + * AdvisingApp\InventoryManagement\Models\MaintenanceActivity + * + * @property string $id + * @property string $asset_id + * @property string|null $maintenance_provider_id + * @property string $details + * @property \Illuminate\Support\Carbon|null $scheduled_date + * @property \Illuminate\Support\Carbon|null $completed_date + * @property \AdvisingApp\InventoryManagement\Enums\MaintenanceActivityStatus $status + * @property string|null $notes + * @property \Illuminate\Support\Carbon|null $created_at + * @property \Illuminate\Support\Carbon|null $updated_at + * @property-read \AdvisingApp\InventoryManagement\Models\Asset $asset + * @property-read \Illuminate\Database\Eloquent\Collection $audits + * @property-read int|null $audits_count + * @property-read \AdvisingApp\InventoryManagement\Models\MaintenanceProvider|null $maintenanceProvider + * @method static \AdvisingApp\InventoryManagement\Database\Factories\MaintenanceActivityFactory factory($count = null, $state = []) + * @method static \Illuminate\Database\Eloquent\Builder|MaintenanceActivity newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|MaintenanceActivity newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|MaintenanceActivity query() + * @method static \Illuminate\Database\Eloquent\Builder|MaintenanceActivity whereAssetId($value) + * @method static \Illuminate\Database\Eloquent\Builder|MaintenanceActivity whereCompletedDate($value) + * @method static \Illuminate\Database\Eloquent\Builder|MaintenanceActivity whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|MaintenanceActivity whereDetails($value) + * @method static \Illuminate\Database\Eloquent\Builder|MaintenanceActivity whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|MaintenanceActivity whereMaintenanceProviderId($value) + * @method static \Illuminate\Database\Eloquent\Builder|MaintenanceActivity whereNotes($value) + * @method static \Illuminate\Database\Eloquent\Builder|MaintenanceActivity whereScheduledDate($value) + * @method static \Illuminate\Database\Eloquent\Builder|MaintenanceActivity whereStatus($value) + * @method static \Illuminate\Database\Eloquent\Builder|MaintenanceActivity whereUpdatedAt($value) + * @mixin \Eloquent + */ + #[\AllowDynamicProperties] + class IdeHelperMaintenanceActivity {} +} + +namespace AdvisingApp\InventoryManagement\Models{ +/** + * AdvisingApp\InventoryManagement\Models\MaintenanceProvider + * + * @property string $id + * @property string $name + * @property \Illuminate\Support\Carbon|null $created_at + * @property \Illuminate\Support\Carbon|null $updated_at + * @property-read \Illuminate\Database\Eloquent\Collection $audits + * @property-read int|null $audits_count + * @property-read \Illuminate\Database\Eloquent\Collection $maintenanceActivities + * @property-read int|null $maintenance_activities_count + * @method static \AdvisingApp\InventoryManagement\Database\Factories\MaintenanceProviderFactory factory($count = null, $state = []) + * @method static \Illuminate\Database\Eloquent\Builder|MaintenanceProvider newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|MaintenanceProvider newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|MaintenanceProvider query() + * @method static \Illuminate\Database\Eloquent\Builder|MaintenanceProvider whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|MaintenanceProvider whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|MaintenanceProvider whereName($value) + * @method static \Illuminate\Database\Eloquent\Builder|MaintenanceProvider whereUpdatedAt($value) + * @mixin \Eloquent + */ + #[\AllowDynamicProperties] + class IdeHelperMaintenanceProvider {} +} + namespace AdvisingApp\KnowledgeBase\Models{ /** * AdvisingApp\KnowledgeBase\Models\KnowledgeBaseCategory @@ -2022,8 +2239,8 @@ class IdeHelperKnowledgeBaseCategory {} * @property string $id * @property string $question * @property bool $public - * @property string|null $solution - * @property string|null $notes + * @property array|null $solution + * @property array|null $notes * @property string|null $quality_id * @property string|null $status_id * @property string|null $category_id @@ -2194,6 +2411,154 @@ class IdeHelperCalendar {} class IdeHelperCalendarEvent {} } +namespace AdvisingApp\MeetingCenter\Models{ +/** + * AdvisingApp\MeetingCenter\Models\Event + * + * @property string $id + * @property string $title + * @property string|null $description + * @property string|null $location + * @property int|null $capacity + * @property \Illuminate\Support\Carbon $starts_at + * @property \Illuminate\Support\Carbon $ends_at + * @property \Illuminate\Support\Carbon|null $created_at + * @property \Illuminate\Support\Carbon|null $updated_at + * @property-read \Illuminate\Database\Eloquent\Collection $attendees + * @property-read int|null $attendees_count + * @property-read \AdvisingApp\MeetingCenter\Models\EventRegistrationForm|null $eventRegistrationForm + * @method static \AdvisingApp\MeetingCenter\Database\Factories\EventFactory factory($count = null, $state = []) + * @method static \Illuminate\Database\Eloquent\Builder|Event newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|Event newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|Event query() + * @method static \Illuminate\Database\Eloquent\Builder|Event whereCapacity($value) + * @method static \Illuminate\Database\Eloquent\Builder|Event whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|Event whereDescription($value) + * @method static \Illuminate\Database\Eloquent\Builder|Event whereEndsAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|Event whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|Event whereLocation($value) + * @method static \Illuminate\Database\Eloquent\Builder|Event whereStartsAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|Event whereTitle($value) + * @method static \Illuminate\Database\Eloquent\Builder|Event whereUpdatedAt($value) + * @mixin \Eloquent + */ + #[\AllowDynamicProperties] + class IdeHelperEvent {} +} + +namespace AdvisingApp\MeetingCenter\Models{ +/** + * AdvisingApp\MeetingCenter\Models\EventAttendee + * + * @property \AdvisingApp\MeetingCenter\Enums\EventAttendeeStatus $status + * @property-read \AdvisingApp\MeetingCenter\Models\Event|null $event + * @property-read \Illuminate\Notifications\DatabaseNotificationCollection $notifications + * @property-read int|null $notifications_count + * @property-read \Illuminate\Database\Eloquent\Collection $prospects + * @property-read int|null $prospects_count + * @property-read \Illuminate\Database\Eloquent\Collection $students + * @property-read int|null $students_count + * @property-read \Illuminate\Database\Eloquent\Collection $submissions + * @property-read int|null $submissions_count + * @method static \Illuminate\Database\Eloquent\Builder|EventAttendee newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|EventAttendee newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|EventAttendee query() + * @mixin \Eloquent + */ + #[\AllowDynamicProperties] + class IdeHelperEventAttendee {} +} + +namespace AdvisingApp\MeetingCenter\Models{ +/** + * AdvisingApp\MeetingCenter\Models\EventRegistrationForm + * + * @property \AdvisingApp\Form\Enums\Rounding $rounding + * @property-read \AdvisingApp\MeetingCenter\Models\Event|null $event + * @property-read \Illuminate\Database\Eloquent\Collection $fields + * @property-read int|null $fields_count + * @property-read \Illuminate\Database\Eloquent\Collection $steps + * @property-read int|null $steps_count + * @property-read \Illuminate\Database\Eloquent\Collection $submissions + * @property-read int|null $submissions_count + * @method static \Illuminate\Database\Eloquent\Builder|EventRegistrationForm newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|EventRegistrationForm newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|EventRegistrationForm onlyTrashed() + * @method static \Illuminate\Database\Eloquent\Builder|EventRegistrationForm query() + * @method static \Illuminate\Database\Eloquent\Builder|EventRegistrationForm withTrashed() + * @method static \Illuminate\Database\Eloquent\Builder|EventRegistrationForm withoutTrashed() + * @mixin \Eloquent + */ + #[\AllowDynamicProperties] + class IdeHelperEventRegistrationForm {} +} + +namespace AdvisingApp\MeetingCenter\Models{ +/** + * AdvisingApp\MeetingCenter\Models\EventRegistrationFormAuthentication + * + * @property-read EventRegistrationForm $submissible + * @property-read \AdvisingApp\MeetingCenter\Models\EventAttendee|null $author + * @method static \Illuminate\Database\Eloquent\Builder|EventRegistrationFormAuthentication newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|EventRegistrationFormAuthentication newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|EventRegistrationFormAuthentication query() + * @mixin \Eloquent + */ + #[\AllowDynamicProperties] + class IdeHelperEventRegistrationFormAuthentication {} +} + +namespace AdvisingApp\MeetingCenter\Models{ +/** + * AdvisingApp\MeetingCenter\Models\EventRegistrationFormField + * + * @property-read \AdvisingApp\MeetingCenter\Models\EventRegistrationFormStep $step + * @property-read \AdvisingApp\MeetingCenter\Models\EventRegistrationForm $submissible + * @method static \Illuminate\Database\Eloquent\Builder|EventRegistrationFormField newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|EventRegistrationFormField newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|EventRegistrationFormField query() + * @mixin \Eloquent + */ + #[\AllowDynamicProperties] + class IdeHelperEventRegistrationFormField {} +} + +namespace AdvisingApp\MeetingCenter\Models{ +/** + * AdvisingApp\MeetingCenter\Models\EventRegistrationFormStep + * + * @property-read \Illuminate\Database\Eloquent\Collection $fields + * @property-read int|null $fields_count + * @property-read \AdvisingApp\MeetingCenter\Models\EventRegistrationForm $submissible + * @method static \Illuminate\Database\Eloquent\Builder|EventRegistrationFormStep newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|EventRegistrationFormStep newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|EventRegistrationFormStep query() + * @mixin \Eloquent + */ + #[\AllowDynamicProperties] + class IdeHelperEventRegistrationFormStep {} +} + +namespace AdvisingApp\MeetingCenter\Models{ +/** + * AdvisingApp\MeetingCenter\Models\EventRegistrationFormSubmission + * + * @property \AdvisingApp\Form\Enums\FormSubmissionRequestDeliveryMethod $request_method + * @property \AdvisingApp\MeetingCenter\Enums\EventAttendeeStatus $attendee_status + * @property-read \AdvisingApp\MeetingCenter\Models\EventAttendee|null $author + * @property-read \Illuminate\Database\Eloquent\Collection $fields + * @property-read int|null $fields_count + * @property-read \App\Models\User $requester + * @property-read \AdvisingApp\MeetingCenter\Models\EventRegistrationForm $submissible + * @method static \Illuminate\Database\Eloquent\Builder|EventRegistrationFormSubmission newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|EventRegistrationFormSubmission newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|EventRegistrationFormSubmission query() + * @mixin \Eloquent + */ + #[\AllowDynamicProperties] + class IdeHelperEventRegistrationFormSubmission {} +} + namespace AdvisingApp\Notification\Models{ /** * AdvisingApp\Notification\Models\OutboundDeliverable @@ -2290,7 +2655,7 @@ class IdeHelperSubscription {} * @property string|null $phone * @property string|null $address * @property string|null $address_2 - * @property string|null $birthdate + * @property \Illuminate\Support\Carbon|null $birthdate * @property string|null $hsgrad * @property string|null $assigned_to_id * @property string|null $created_by_id @@ -2744,6 +3109,7 @@ class IdeHelperProgram {} * AdvisingApp\StudentDataModel\Models\Student * * @property string $display_name + * @property string $mobile * @property-read \Illuminate\Database\Eloquent\Collection $alerts * @property-read int|null $alerts_count * @property-read \Illuminate\Database\Eloquent\Collection $applicationSubmissions diff --git a/app-modules/assistant/src/Filament/Pages/ManageAiSettings.php b/app-modules/assistant/src/Filament/Pages/ManageAiSettings.php index f2b7567936..5297dc5be9 100644 --- a/app-modules/assistant/src/Filament/Pages/ManageAiSettings.php +++ b/app-modules/assistant/src/Filament/Pages/ManageAiSettings.php @@ -37,7 +37,6 @@ namespace AdvisingApp\Assistant\Filament\Pages; use App\Models\User; -use App\Enums\Feature; use Filament\Forms\Form; use Filament\Pages\SettingsPage; use Filament\Forms\Components\Textarea; @@ -58,7 +57,9 @@ public static function shouldRegisterNavigation(): bool /** @var User $user */ $user = auth()->user(); - return $user->can([Feature::PersonalAssistant->getGateName(), 'assistant.access_ai_settings']); + // TODO: Feature/License Gate | if has AI License + + return $user->can(['assistant.access_ai_settings']); } public function mount(): void @@ -66,7 +67,9 @@ public function mount(): void /** @var User $user */ $user = auth()->user(); - abort_unless($user->can([Feature::PersonalAssistant->getGateName(), 'assistant.access_ai_settings']), 403); + // TODO: Feature/License Gate | if has AI License + + abort_unless($user->can(['assistant.access_ai_settings']), 403); parent::mount(); } diff --git a/app-modules/assistant/src/Filament/Pages/PersonalAssistant.php b/app-modules/assistant/src/Filament/Pages/PersonalAssistant.php index 1683ec61f8..286e93fd51 100644 --- a/app-modules/assistant/src/Filament/Pages/PersonalAssistant.php +++ b/app-modules/assistant/src/Filament/Pages/PersonalAssistant.php @@ -37,7 +37,6 @@ namespace AdvisingApp\Assistant\Filament\Pages; use App\Models\User; -use App\Enums\Feature; use Filament\Forms\Get; use Filament\Pages\Page; use Livewire\Attributes\On; @@ -49,7 +48,6 @@ use Filament\Actions\StaticAction; use Illuminate\Support\Collection; use Filament\Forms\Components\Radio; -use Illuminate\Support\Facades\Gate; use Filament\Forms\Components\Select; use Filament\Support\Enums\Alignment; use Filament\Support\Enums\ActionSize; @@ -110,12 +108,14 @@ public static function shouldRegisterNavigation(): bool /** @var User $user */ $user = auth()->user(); - return Gate::check(Feature::PersonalAssistant->getGateName()) && $user->can('assistant.access'); + // TODO: Feature/License Gate | if has AI License + + return $user->can('assistant.access'); } public function mount(): void { - $this->authorize(Feature::PersonalAssistant->getGateName()); + // TODO: Feature/License Gate | if has AI License $this->authorize('assistant.access'); $this->consentAgreement = ConsentAgreement::where('type', ConsentAgreementType::AzureOpenAI)->first(); diff --git a/app-modules/assistant/src/Policies/AssistantChatMessageLogPolicy.php b/app-modules/assistant/src/Policies/AssistantChatMessageLogPolicy.php index 5addc25240..f0489b5ea9 100644 --- a/app-modules/assistant/src/Policies/AssistantChatMessageLogPolicy.php +++ b/app-modules/assistant/src/Policies/AssistantChatMessageLogPolicy.php @@ -36,7 +36,6 @@ namespace AdvisingApp\Assistant\Policies; -use App\Enums\Feature; use App\Models\Authenticatable; use Illuminate\Auth\Access\Response; use App\Concerns\FeatureAccessEnforcedPolicyBefore; @@ -90,8 +89,7 @@ public function forceDelete(Authenticatable $authenticatable, AssistantChatMessa protected function requiredFeatures(): array { - return [ - Feature::PersonalAssistant, - ]; + // TODO: Feature/License Gate | if has AI License + return []; } } diff --git a/app-modules/authorization/config/roles/web/license_management.php b/app-modules/authorization/config/roles/web/license_management.php new file mode 100644 index 0000000000..ac07305bb6 --- /dev/null +++ b/app-modules/authorization/config/roles/web/license_management.php @@ -0,0 +1,43 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +return [ + 'model' => [ + 'license' => [ + '*', + ], + ], +]; diff --git a/app-modules/authorization/database/migrations/2024_01_02_225406_create_licenses_table.php b/app-modules/authorization/database/migrations/2024_01_02_225406_create_licenses_table.php new file mode 100644 index 0000000000..eac079e191 --- /dev/null +++ b/app-modules/authorization/database/migrations/2024_01_02_225406_create_licenses_table.php @@ -0,0 +1,55 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +use Illuminate\Database\Query\Builder; +use Illuminate\Database\Migrations\Migration; +use Tpetry\PostgresqlEnhanced\Schema\Blueprint; +use Tpetry\PostgresqlEnhanced\Support\Facades\Schema; + +return new class () extends Migration { + public function up(): void + { + Schema::create('licenses', function (Blueprint $table) { + $table->uuid('id')->primary(); + $table->foreignUuid('user_id')->constrained('users')->cascadeOnDelete(); + $table->string('type'); + $table->timestamps(); + $table->softDeletes(); + + $table->uniqueIndex(['user_id', 'type'])->where(fn (Builder $condition) => $condition->whereNull('deleted_at')); + }); + } +}; diff --git a/app-modules/authorization/src/Enums/LicenseType.php b/app-modules/authorization/src/Enums/LicenseType.php new file mode 100644 index 0000000000..5e7e9d06db --- /dev/null +++ b/app-modules/authorization/src/Enums/LicenseType.php @@ -0,0 +1,74 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\Authorization\Enums; + +use App\Settings\LicenseSettings; +use Filament\Support\Contracts\HasLabel; +use AdvisingApp\Authorization\Models\License; + +enum LicenseType: string implements HasLabel +{ + case ConversationalAi = 'conversational_ai'; + + case RetentionCrm = 'retention_crm'; + + case RecruitmentCrm = 'recruitment_crm'; + + public function getLabel(): ?string + { + return match ($this) { + LicenseType::ConversationalAi => 'Conversational AI', + LicenseType::RetentionCrm => 'Retention CRM', + LicenseType::RecruitmentCrm => 'Recruitment CRM', + }; + } + + public function hasAvailableLicenses(): bool + { + $totalLicensesInUse = License::query()->where('type', $this)->count(); + + $licenseSettings = app(LicenseSettings::class); + + $licenseLimit = match ($this) { + LicenseType::ConversationalAi => $licenseSettings->data->limits->conversationalAiSeats, + LicenseType::RetentionCrm => $licenseSettings->data->limits->retentionCrmSeats, + LicenseType::RecruitmentCrm => $licenseSettings->data->limits->recruitmentCrmSeats, + }; + + return $totalLicensesInUse < $licenseLimit; + } +} diff --git a/app-modules/authorization/src/Models/License.php b/app-modules/authorization/src/Models/License.php new file mode 100644 index 0000000000..91dc3f04c9 --- /dev/null +++ b/app-modules/authorization/src/Models/License.php @@ -0,0 +1,67 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\Authorization\Models; + +use App\Models\User; +use App\Models\BaseModel; +use OwenIt\Auditing\Contracts\Auditable; +use Illuminate\Database\Eloquent\SoftDeletes; +use AdvisingApp\Authorization\Enums\LicenseType; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use AdvisingApp\Audit\Models\Concerns\Auditable as AuditableConcern; + +/** + * @mixin IdeHelperLicense + */ +class License extends BaseModel implements Auditable +{ + use AuditableConcern; + use SoftDeletes; + + protected $fillable = [ + 'type', + ]; + + protected $casts = [ + 'type' => LicenseType::class, + ]; + + public function user(): BelongsTo + { + return $this->belongsTo(User::class, 'user_id'); + } +} diff --git a/app-modules/authorization/src/Observers/LicenseObserver.php b/app-modules/authorization/src/Observers/LicenseObserver.php new file mode 100644 index 0000000000..c1280f5f78 --- /dev/null +++ b/app-modules/authorization/src/Observers/LicenseObserver.php @@ -0,0 +1,50 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\Authorization\Observers; + +use Exception; +use AdvisingApp\Authorization\Models\License; + +class LicenseObserver +{ + public function creating(License $license): void + { + if (! $license->type->hasAvailableLicenses()) { + throw new Exception("There are no available {$license->type->getLabel()} licenses."); + } + } +} diff --git a/app-modules/authorization/src/Providers/AuthorizationServiceProvider.php b/app-modules/authorization/src/Providers/AuthorizationServiceProvider.php index 22a4eba828..ce36123f8b 100644 --- a/app-modules/authorization/src/Providers/AuthorizationServiceProvider.php +++ b/app-modules/authorization/src/Providers/AuthorizationServiceProvider.php @@ -40,6 +40,7 @@ use Illuminate\Support\Facades\Event; use Illuminate\Support\ServiceProvider; use AdvisingApp\Authorization\Models\Role; +use AdvisingApp\Authorization\Models\License; use AdvisingApp\Authorization\Models\RoleGroup; use AdvisingApp\Authorization\Models\Permission; use AdvisingApp\Authorization\AuthorizationPlugin; @@ -48,6 +49,7 @@ use Illuminate\Database\Eloquent\Relations\Relation; use SocialiteProviders\Google\GoogleExtendSocialite; use AdvisingApp\Authorization\AuthorizationRoleRegistry; +use AdvisingApp\Authorization\Observers\LicenseObserver; use AdvisingApp\Authorization\AuthorizationPermissionRegistry; class AuthorizationServiceProvider extends ServiceProvider @@ -73,8 +75,11 @@ public function boot(AuthorizationPermissionRegistry $permissionRegistry, Author 'role' => Role::class, 'permission' => Permission::class, 'role_group' => RoleGroup::class, + 'license' => License::class, ]); + $this->registerObservers(); + $permissionRegistry->registerApiPermissions( module: 'authorization', path: 'permissions/api/custom' @@ -105,4 +110,9 @@ public function boot(AuthorizationPermissionRegistry $permissionRegistry, Author listener: GoogleExtendSocialite::class . '@handle' ); } + + public function registerObservers(): void + { + License::observe(LicenseObserver::class); + } } diff --git a/app-modules/authorization/src/Rules/LicenseTypeUsageRule.php b/app-modules/authorization/src/Rules/LicenseTypeUsageRule.php new file mode 100644 index 0000000000..16ed3c0982 --- /dev/null +++ b/app-modules/authorization/src/Rules/LicenseTypeUsageRule.php @@ -0,0 +1,53 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\Authorization\Rules; + +use Closure; +use AdvisingApp\Authorization\Enums\LicenseType; +use Illuminate\Contracts\Validation\ValidationRule; + +class LicenseTypeUsageRule implements ValidationRule +{ + public function validate(string $attribute, mixed $value, Closure $fail): void + { + $licenseType = LicenseType::from($value); + + if (! $licenseType->hasAvailableLicenses()) { + $fail("There are no available {$licenseType->getLabel()} licenses."); + } + } +} diff --git a/app-modules/consent/src/Filament/Resources/ConsentAgreementResource/Pages/ListConsentAgreements.php b/app-modules/consent/src/Filament/Resources/ConsentAgreementResource/Pages/ListConsentAgreements.php index 60a743fc28..93bc6bc87c 100644 --- a/app-modules/consent/src/Filament/Resources/ConsentAgreementResource/Pages/ListConsentAgreements.php +++ b/app-modules/consent/src/Filament/Resources/ConsentAgreementResource/Pages/ListConsentAgreements.php @@ -37,7 +37,6 @@ namespace AdvisingApp\Consent\Filament\Resources\ConsentAgreementResource\Pages; use App\Models\User; -use App\Enums\Feature; use Filament\Forms\Form; use Filament\Tables\Table; use App\Filament\Columns\IdColumn; @@ -72,7 +71,9 @@ public static function shouldRegisterNavigation(array $parameters = []): bool /** @var User $user */ $user = auth()->user(); - return $user->can([Feature::PersonalAssistant->getGateName(), 'consent_agreement.view-any', 'consent_agreement.*.view', 'consent_agreement.*.update']); + // TODO: Feature/License Gate | if has AI License, may need to prevent mount as well + + return $user->can(['consent_agreement.view-any', 'consent_agreement.*.view', 'consent_agreement.*.update']); } public function form(Form $form): Form diff --git a/app-modules/consent/src/Policies/ConsentAgreementPolicy.php b/app-modules/consent/src/Policies/ConsentAgreementPolicy.php index c1fab30e1c..1f8a71b82f 100644 --- a/app-modules/consent/src/Policies/ConsentAgreementPolicy.php +++ b/app-modules/consent/src/Policies/ConsentAgreementPolicy.php @@ -36,7 +36,6 @@ namespace AdvisingApp\Consent\Policies; -use App\Enums\Feature; use App\Models\Authenticatable; use Illuminate\Auth\Access\Response; use AdvisingApp\Consent\Models\ConsentAgreement; @@ -93,8 +92,7 @@ public function forceDelete(Authenticatable $authenticatable, ConsentAgreement $ protected function requiredFeatures(): array { - return [ - Feature::PersonalAssistant, - ]; + // TODO: Feature/License Gate | if has AI License + return []; } } diff --git a/app-modules/engagement/src/Providers/EngagementServiceProvider.php b/app-modules/engagement/src/Providers/EngagementServiceProvider.php index c37579c893..5f9f784093 100644 --- a/app-modules/engagement/src/Providers/EngagementServiceProvider.php +++ b/app-modules/engagement/src/Providers/EngagementServiceProvider.php @@ -84,9 +84,9 @@ public function boot(): void ->withoutOverlapping(); }); - $this->registerRolesAndPermissions(); - $this->registerObservers(); + + $this->registerRolesAndPermissions(); } public function registerObservers(): void diff --git a/app-modules/form/src/Actions/GenerateFormKitSchema.php b/app-modules/form/src/Actions/GenerateFormKitSchema.php index 1ce5fa3530..f51dbc2029 100644 --- a/app-modules/form/src/Actions/GenerateFormKitSchema.php +++ b/app-modules/form/src/Actions/GenerateFormKitSchema.php @@ -45,29 +45,6 @@ class GenerateFormKitSchema { public function __invoke(Submissible $submissible): array { - if ($submissible->is_wizard) { - $submissible->loadMissing([ - 'steps' => [ - 'fields', - ], - ]); - - $content = $this->wizardContent($submissible); - } else { - $submissible->loadMissing([ - 'fields', - ]); - - $content = [ - ...$this->content($submissible->content['content'] ?? [], $submissible->fields->keyBy('id')), - [ - '$formkit' => 'submit', - 'label' => 'Submit', - 'disabled' => '$get(form).state.valid !== true', - ], - ]; - } - return [ '$cmp' => 'FormKit', 'props' => [ @@ -77,7 +54,7 @@ public function __invoke(Submissible $submissible): array 'plugins' => '$plugins', 'actions' => false, ], - 'children' => $content, + 'children' => $this->generateContent($submissible), ]; } @@ -271,4 +248,32 @@ public function wizardContent(Submissible $submissible): array ], ]; } + + protected function generateContent(Submissible $submissible): array + { + if ($submissible->is_wizard) { + $submissible->loadMissing([ + 'steps' => [ + 'fields', + ], + ]); + + $content = $this->wizardContent($submissible); + } else { + $submissible->loadMissing([ + 'fields', + ]); + + $content = [ + ...$this->content($submissible->content['content'] ?? [], $submissible->fields->keyBy('id')), + [ + '$formkit' => 'submit', + 'label' => 'Submit', + 'disabled' => '$get(form).state.valid !== true', + ], + ]; + } + + return $content; + } } diff --git a/app-modules/form/src/Actions/GenerateSubmissibleEmbedCode.php b/app-modules/form/src/Actions/GenerateSubmissibleEmbedCode.php index 41140906d9..339d06623d 100644 --- a/app-modules/form/src/Actions/GenerateSubmissibleEmbedCode.php +++ b/app-modules/form/src/Actions/GenerateSubmissibleEmbedCode.php @@ -42,6 +42,7 @@ use AdvisingApp\Survey\Models\Survey; use AdvisingApp\Form\Models\Submissible; use AdvisingApp\Application\Models\Application; +use AdvisingApp\MeetingCenter\Models\EventRegistrationForm; class GenerateSubmissibleEmbedCode { @@ -75,6 +76,16 @@ public function handle(Submissible $submissible): string EOD; })(), + EventRegistrationForm::class => (function () use ($submissible) { + /** @var EventRegistrationForm $submissible */ + $scriptUrl = url('js/widgets/events/advising-app-event-registration-form-widget.js?'); + $formDefinitionUrl = URL::signedRoute('event-registration.define', ['event' => $submissible->event]); + + return << + + EOD; + })(), default => throw new Exception('Unsupported submissible type.'), }; } diff --git a/app-modules/form/src/Models/SubmissibleAuthentication.php b/app-modules/form/src/Models/SubmissibleAuthentication.php index 9e6c8d5523..3d6bb26158 100644 --- a/app-modules/form/src/Models/SubmissibleAuthentication.php +++ b/app-modules/form/src/Models/SubmissibleAuthentication.php @@ -41,7 +41,6 @@ use App\Models\Attributes\NoPermissions; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\MassPrunable; -use Illuminate\Database\Eloquent\Relations\MorphTo; use Illuminate\Database\Eloquent\Relations\BelongsTo; /** @@ -66,7 +65,7 @@ public function prunable(): Builder ->where('created_at', '<', now()->subMonth()); } - public function author(): MorphTo + public function author(): BelongsTo { return $this->morphTo(); } diff --git a/app-modules/form/src/Models/Submission.php b/app-modules/form/src/Models/Submission.php index aa948d8ca1..86f3e41f3e 100644 --- a/app-modules/form/src/Models/Submission.php +++ b/app-modules/form/src/Models/Submission.php @@ -40,7 +40,6 @@ use AdvisingApp\Prospect\Models\Prospect; use Illuminate\Database\Eloquent\Collection; use AdvisingApp\StudentDataModel\Models\Student; -use Illuminate\Database\Eloquent\Relations\MorphTo; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsToMany; @@ -55,7 +54,7 @@ abstract public function submissible(): BelongsTo; abstract public function fields(): BelongsToMany; - public function author(): MorphTo + public function author(): BelongsTo { return $this ->morphTo('author'); diff --git a/app-modules/form/src/Policies/FormPolicy.php b/app-modules/form/src/Policies/FormPolicy.php index d6d72f6300..14c33e8645 100644 --- a/app-modules/form/src/Policies/FormPolicy.php +++ b/app-modules/form/src/Policies/FormPolicy.php @@ -105,6 +105,6 @@ public function forceDelete(Authenticatable $authenticatable, Form $form): Respo protected function requiredFeatures(): array { - return [Feature::DynamicForms]; + return [Feature::OnlineForms]; } } diff --git a/app-modules/inventory-management/config/roles/api/inventory_management.php b/app-modules/inventory-management/config/roles/api/inventory_management.php index 268edc7499..d7c70b0afb 100644 --- a/app-modules/inventory-management/config/roles/api/inventory_management.php +++ b/app-modules/inventory-management/config/roles/api/inventory_management.php @@ -48,6 +48,12 @@ 'asset_type' => [ '*', ], + 'asset_check_in' => [ + '*', + ], + 'asset_check_out' => [ + '*', + ], 'maintenance_activity' => [ '*', ], diff --git a/app-modules/inventory-management/config/roles/web/inventory_management.php b/app-modules/inventory-management/config/roles/web/inventory_management.php index 268edc7499..d7c70b0afb 100644 --- a/app-modules/inventory-management/config/roles/web/inventory_management.php +++ b/app-modules/inventory-management/config/roles/web/inventory_management.php @@ -48,6 +48,12 @@ 'asset_type' => [ '*', ], + 'asset_check_in' => [ + '*', + ], + 'asset_check_out' => [ + '*', + ], 'maintenance_activity' => [ '*', ], diff --git a/app-modules/inventory-management/database/factories/AssetCheckInFactory.php b/app-modules/inventory-management/database/factories/AssetCheckInFactory.php new file mode 100644 index 0000000000..aec0066bd4 --- /dev/null +++ b/app-modules/inventory-management/database/factories/AssetCheckInFactory.php @@ -0,0 +1,79 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\InventoryManagement\Database\Factories; + +use App\Models\User; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; +use AdvisingApp\InventoryManagement\Models\Asset; +use Illuminate\Database\Eloquent\Factories\Factory; +use Illuminate\Database\Eloquent\Relations\Relation; + +/** + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\AdvisingApp\InventoryManagement\Models\AssetCheckIn> + */ +class AssetCheckInFactory extends Factory +{ + public function definition(): array + { + $checkedInBy = User::factory()->create(); + + return [ + 'asset_id' => Asset::factory(), + 'checked_in_by_type' => $checkedInBy->getMorphClass(), + 'checked_in_by_id' => $checkedInBy->getKey(), + 'checked_in_from_type' => fake()->randomElement([ + (new Student())->getMorphClass(), + (new Prospect())->getMorphClass(), + ]), + 'checked_in_from_id' => function (array $attributes) { + $checkedInFromClass = Relation::getMorphedModel($attributes['checked_in_from_type']); + + /** @var Student|Prospect $senderModel */ + $checkedInFromModel = new $checkedInFromClass(); + + $checkedInFromModel = $checkedInFromClass === Student::class + ? Student::inRandomOrder()->first() ?? Student::factory()->create() + : $checkedInFromModel::factory()->create(); + + return $checkedInFromModel->getKey(); + }, + 'checked_in_at' => fake()->dateTimeBetween('-1 year', 'now'), + 'notes' => fake()->paragraph(), + ]; + } +} diff --git a/app-modules/inventory-management/database/factories/AssetCheckOutFactory.php b/app-modules/inventory-management/database/factories/AssetCheckOutFactory.php new file mode 100644 index 0000000000..908cc3623d --- /dev/null +++ b/app-modules/inventory-management/database/factories/AssetCheckOutFactory.php @@ -0,0 +1,86 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\InventoryManagement\Database\Factories; + +use Carbon\Carbon; +use App\Models\User; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; +use AdvisingApp\InventoryManagement\Models\Asset; +use Illuminate\Database\Eloquent\Factories\Factory; +use Illuminate\Database\Eloquent\Relations\Relation; + +/** + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\AdvisingApp\InventoryManagement\Models\AssetCheckOut> + */ +class AssetCheckOutFactory extends Factory +{ + public function definition(): array + { + $checkedOutBy = User::factory()->create(); + + return [ + 'asset_id' => Asset::factory(), + 'asset_check_in_id' => null, + 'checked_out_by_type' => $checkedOutBy->getMorphClass(), + 'checked_out_by_id' => $checkedOutBy->getKey(), + 'checked_out_to_type' => fake()->randomElement([ + (new Student())->getMorphClass(), + (new Prospect())->getMorphClass(), + ]), + 'checked_out_to_id' => function (array $attributes) { + $checkedOutToClass = Relation::getMorphedModel($attributes['checked_out_to_type']); + + /** @var Student|Prospect $senderModel */ + $checkedOutToModel = new $checkedOutToClass(); + + $checkedOutToModel = $checkedOutToClass === Student::class + ? Student::inRandomOrder()->first() ?? Student::factory()->create() + : $checkedOutToModel::factory()->create(); + + return $checkedOutToModel->getKey(); + }, + 'checked_out_at' => fake()->dateTimeBetween('-1 year', 'now'), + 'expected_check_in_at' => function (array $attributes) { + $checkedOutAt = Carbon::parse($attributes['checked_out_at']); + + return fake()->dateTimeBetween($checkedOutAt->addDays(1), $checkedOutAt->addDays(50)); + }, + 'notes' => fake()->paragraph(), + ]; + } +} diff --git a/app-modules/inventory-management/database/factories/AssetStatusFactory.php b/app-modules/inventory-management/database/factories/AssetStatusFactory.php index 75ea75e646..412da2f51c 100644 --- a/app-modules/inventory-management/database/factories/AssetStatusFactory.php +++ b/app-modules/inventory-management/database/factories/AssetStatusFactory.php @@ -37,6 +37,7 @@ namespace AdvisingApp\InventoryManagement\Database\Factories; use Illuminate\Database\Eloquent\Factories\Factory; +use AdvisingApp\InventoryManagement\Enums\SystemAssetStatusClassification; /** * @extends \Illuminate\Database\Eloquent\Factories\Factory<\AdvisingApp\InventoryManagement\Models\AssetStatus> @@ -46,6 +47,7 @@ class AssetStatusFactory extends Factory public function definition(): array { return [ + 'classification' => SystemAssetStatusClassification::Unavailable, 'name' => fake()->word(), ]; } diff --git a/app-modules/inventory-management/database/migrations/2023_12_26_181818_create_asset_types_table.php b/app-modules/inventory-management/database/migrations/2023_12_26_181818_create_asset_types_table.php index c2d2c62e99..64a6b5b6f8 100644 --- a/app-modules/inventory-management/database/migrations/2023_12_26_181818_create_asset_types_table.php +++ b/app-modules/inventory-management/database/migrations/2023_12_26_181818_create_asset_types_table.php @@ -45,6 +45,7 @@ public function up(): void $table->uuid('id')->primary(); $table->string('name'); $table->timestamps(); + $table->softDeletes(); }); } }; diff --git a/app-modules/inventory-management/database/migrations/2023_12_26_181828_create_asset_statuses_table.php b/app-modules/inventory-management/database/migrations/2023_12_26_181828_create_asset_statuses_table.php index c50e496550..01fe18f9cc 100644 --- a/app-modules/inventory-management/database/migrations/2023_12_26_181828_create_asset_statuses_table.php +++ b/app-modules/inventory-management/database/migrations/2023_12_26_181828_create_asset_statuses_table.php @@ -43,8 +43,10 @@ public function up(): void { Schema::create('asset_statuses', function (Blueprint $table) { $table->uuid('id')->primary(); + $table->string('classification'); $table->string('name'); $table->timestamps(); + $table->softDeletes(); }); } }; diff --git a/app-modules/inventory-management/database/migrations/2023_12_26_181837_create_asset_locations_table.php b/app-modules/inventory-management/database/migrations/2023_12_26_181837_create_asset_locations_table.php index f3264d6e79..6409f01e97 100644 --- a/app-modules/inventory-management/database/migrations/2023_12_26_181837_create_asset_locations_table.php +++ b/app-modules/inventory-management/database/migrations/2023_12_26_181837_create_asset_locations_table.php @@ -45,6 +45,7 @@ public function up(): void $table->uuid('id')->primary(); $table->string('name'); $table->timestamps(); + $table->softDeletes(); }); } }; diff --git a/app-modules/inventory-management/database/migrations/2023_12_26_181855_create_assets_table.php b/app-modules/inventory-management/database/migrations/2023_12_26_181855_create_assets_table.php index 57de8650b8..46ee693db6 100644 --- a/app-modules/inventory-management/database/migrations/2023_12_26_181855_create_assets_table.php +++ b/app-modules/inventory-management/database/migrations/2023_12_26_181855_create_assets_table.php @@ -51,6 +51,7 @@ public function up(): void $table->foreignUuid('location_id')->constrained('asset_locations'); $table->timestamp('purchase_date'); $table->timestamps(); + $table->softDeletes(); }); } }; diff --git a/app-modules/inventory-management/database/migrations/2023_12_27_175502_create_maintenance_providers_table.php b/app-modules/inventory-management/database/migrations/2023_12_27_175502_create_maintenance_providers_table.php index c3ca71714d..f12366afe3 100644 --- a/app-modules/inventory-management/database/migrations/2023_12_27_175502_create_maintenance_providers_table.php +++ b/app-modules/inventory-management/database/migrations/2023_12_27_175502_create_maintenance_providers_table.php @@ -45,6 +45,7 @@ public function up(): void $table->uuid('id')->primary(); $table->string('name'); $table->timestamps(); + $table->softDeletes(); }); } }; diff --git a/app-modules/inventory-management/database/migrations/2023_12_27_175512_create_maintenance_activities_table.php b/app-modules/inventory-management/database/migrations/2023_12_27_175512_create_maintenance_activities_table.php index 3caa469ecd..b78014de87 100644 --- a/app-modules/inventory-management/database/migrations/2023_12_27_175512_create_maintenance_activities_table.php +++ b/app-modules/inventory-management/database/migrations/2023_12_27_175512_create_maintenance_activities_table.php @@ -55,6 +55,7 @@ public function up(): void $table->string('status')->default(MaintenanceActivityStatus::Scheduled); $table->longText('notes')->nullable(); $table->timestamps(); + $table->softDeletes(); }); } }; diff --git a/app-modules/inventory-management/database/migrations/2023_12_28_174428_create_asset_check_ins_table.php b/app-modules/inventory-management/database/migrations/2023_12_28_174428_create_asset_check_ins_table.php new file mode 100644 index 0000000000..f837c2993a --- /dev/null +++ b/app-modules/inventory-management/database/migrations/2023_12_28_174428_create_asset_check_ins_table.php @@ -0,0 +1,57 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +use Illuminate\Support\Facades\Schema; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +return new class () extends Migration { + public function up(): void + { + Schema::create('asset_check_ins', function (Blueprint $table) { + $table->uuid('id')->primary(); + $table->foreignUuid('asset_id')->constrained('assets'); + $table->string('checked_in_by_type')->nullable(); + $table->string('checked_in_by_id')->nullable(); + $table->string('checked_in_from_type'); + $table->string('checked_in_from_id'); + $table->timestamp('checked_in_at'); + $table->longText('notes')->nullable(); + $table->timestamps(); + $table->softDeletes(); + }); + } +}; diff --git a/app-modules/inventory-management/database/migrations/2023_12_28_174437_create_asset_check_outs_table.php b/app-modules/inventory-management/database/migrations/2023_12_28_174437_create_asset_check_outs_table.php new file mode 100644 index 0000000000..4dd77f8ed2 --- /dev/null +++ b/app-modules/inventory-management/database/migrations/2023_12_28_174437_create_asset_check_outs_table.php @@ -0,0 +1,59 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +use Illuminate\Support\Facades\Schema; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +return new class () extends Migration { + public function up(): void + { + Schema::create('asset_check_outs', function (Blueprint $table) { + $table->uuid('id')->primary(); + $table->foreignUuid('asset_id')->constrained('assets'); + $table->foreignUuid('asset_check_in_id')->nullable()->constrained('asset_check_ins'); + $table->string('checked_out_by_type')->nullable(); + $table->string('checked_out_by_id')->nullable(); + $table->string('checked_out_to_type'); + $table->string('checked_out_to_id'); + $table->timestamp('checked_out_at'); + $table->timestamp('expected_check_in_at')->nullable(); + $table->longText('notes')->nullable(); + $table->timestamps(); + $table->softDeletes(); + }); + } +}; diff --git a/app-modules/inventory-management/database/seeders/AssetSeeder.php b/app-modules/inventory-management/database/seeders/AssetSeeder.php index d5638da918..9dc2eab33c 100644 --- a/app-modules/inventory-management/database/seeders/AssetSeeder.php +++ b/app-modules/inventory-management/database/seeders/AssetSeeder.php @@ -48,9 +48,9 @@ public function run(): void ->count(10) ->create() ->each(function (Asset $asset) { - $maintenanceActivitiesCount = rand(0, 10); + $entityCount = rand(0, 10); - for ($i = 0; $i < $maintenanceActivitiesCount; $i++) { + for ($i = 0; $i < $entityCount; $i++) { MaintenanceActivity::factory() ->randomizeState() ->for($asset, 'asset') diff --git a/app-modules/inventory-management/database/seeders/AssetStatusSeeder.php b/app-modules/inventory-management/database/seeders/AssetStatusSeeder.php index 5ae922356b..e722caff2b 100644 --- a/app-modules/inventory-management/database/seeders/AssetStatusSeeder.php +++ b/app-modules/inventory-management/database/seeders/AssetStatusSeeder.php @@ -38,6 +38,7 @@ use Illuminate\Database\Seeder; use AdvisingApp\InventoryManagement\Models\AssetStatus; +use AdvisingApp\InventoryManagement\Enums\SystemAssetStatusClassification; class AssetStatusSeeder extends Seeder { @@ -46,16 +47,20 @@ public function run(): void AssetStatus::factory() ->createMany( [ - ['name' => 'In Use'], - ['name' => 'Available'], + [ + 'name' => 'Available', + 'classification' => SystemAssetStatusClassification::Available, + ], + [ + 'name' => 'In Use', + 'classification' => SystemAssetStatusClassification::CheckedOut, + ], ['name' => 'Under Maintenance'], ['name' => 'Out of Service'], ['name' => 'Reserved'], - ['name' => 'On Loan'], ['name' => 'Awaiting Repair'], ['name' => 'Lost'], ['name' => 'Damaged'], - ['name' => 'New'], ] ); } diff --git a/app-modules/inventory-management/src/Enums/SystemAssetStatusClassification.php b/app-modules/inventory-management/src/Enums/SystemAssetStatusClassification.php new file mode 100644 index 0000000000..ba9704cb95 --- /dev/null +++ b/app-modules/inventory-management/src/Enums/SystemAssetStatusClassification.php @@ -0,0 +1,60 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\InventoryManagement\Enums; + +use Filament\Support\Contracts\HasLabel; + +enum SystemAssetStatusClassification: string implements HasLabel +{ + // TODO Implement a rule that only one asset status can be classified as this + case Available = 'available'; + + // TODO Implement a rule that only one asset status can be classified as this + case CheckedOut = 'checked_out'; + + case Unavailable = 'unavailable'; + + case Custom = 'custom'; + + public function getLabel(): ?string + { + return match ($this) { + self::CheckedOut => 'Checked Out', + default => $this->name + }; + } +} diff --git a/app-modules/inventory-management/src/Filament/Actions/CheckInAssetHeaderAction.php b/app-modules/inventory-management/src/Filament/Actions/CheckInAssetHeaderAction.php new file mode 100644 index 0000000000..9419287ff7 --- /dev/null +++ b/app-modules/inventory-management/src/Filament/Actions/CheckInAssetHeaderAction.php @@ -0,0 +1,106 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\InventoryManagement\Filament\Actions; + +use Filament\Actions\Action; +use Filament\Forms\Components\Select; +use Filament\Forms\Components\Textarea; +use Filament\Forms\Components\DateTimePicker; +use AdvisingApp\InventoryManagement\Models\Asset; +use AdvisingApp\InventoryManagement\Models\AssetStatus; + +class CheckInAssetHeaderAction extends Action +{ + protected function setUp(): void + { + parent::setUp(); + + $this->button(); + + $this->label(__('Check In')); + + /** @var Asset $asset */ + $asset = $this->getRecord(); + + $this->modalHeading(__("Check in {$asset->name}")); + + $this->modalSubmitActionLabel(__('Done')); + + $this->successNotificationTitle(__("Successfully checked in {$asset->name}")); + + $this->form([ + Textarea::make('notes') + ->autofocus(), + Select::make('status_id') + ->relationship('status', 'name') + ->preload() + ->label('Status') + ->default(AssetStatus::available()->first()->id) + ->required() + ->exists((new AssetStatus())->getTable(), 'id'), + DateTimePicker::make('checked_in_at') + ->label('Checked in at') + ->default(now()), + ]); + + $this->action(function (array $data): void { + /** @var Asset $asset */ + $asset = $this->getRecord(); + + if (! $asset->isCheckedOut()) { + $this->failure(); + } + + $asset->checkIns()->create([ + 'checked_in_by_type' => auth()->user()?->getMorphClass(), + 'checked_in_by_id' => auth()->user()?->id, + // TODO Should this always simply be the latest check out, or do we want to support + // The possibility that the person checking in is different than whoever checked out? + 'checked_in_from_type' => $asset->latestCheckOut->checked_out_to_type, + 'checked_in_from_id' => $asset->latestCheckOut->checked_out_to_id, + 'notes' => $data['notes'], + 'checked_in_at' => $data['checked_in_at'] ?? now(), + ]); + + $asset->update([ + 'status_id' => $data['status_id'], + ]); + + $this->success(); + }); + } +} diff --git a/app-modules/inventory-management/src/Filament/Actions/CheckOutAssetHeaderAction.php b/app-modules/inventory-management/src/Filament/Actions/CheckOutAssetHeaderAction.php new file mode 100644 index 0000000000..f417c58289 --- /dev/null +++ b/app-modules/inventory-management/src/Filament/Actions/CheckOutAssetHeaderAction.php @@ -0,0 +1,124 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\InventoryManagement\Filament\Actions; + +use Filament\Forms\Get; +use Filament\Actions\Action; +use Filament\Forms\Components\Radio; +use Filament\Forms\Components\Select; +use Filament\Forms\Components\Textarea; +use AdvisingApp\Prospect\Models\Prospect; +use Filament\Forms\Components\DateTimePicker; +use AdvisingApp\StudentDataModel\Models\Student; +use AdvisingApp\InventoryManagement\Models\Asset; +use AdvisingApp\InventoryManagement\Models\AssetStatus; + +class CheckOutAssetHeaderAction extends Action +{ + protected function setUp(): void + { + parent::setUp(); + + $this->button(); + + $this->label(__('Check Out')); + + /** @var Asset $asset */ + $asset = $this->getRecord(); + + $this->modalHeading(__("Check out {$asset->name}")); + + $this->modalSubmitActionLabel(__('Done')); + + $this->successNotificationTitle(__("Successfully checked out {$asset->name}")); + + $this->form([ + Radio::make('checked_out_to_type') + ->label('Check out to') + ->options([ + Student::class => 'Student', + Prospect::class => 'Prospect', + ]) + ->default(Student::class) + ->required() + ->live(), + Select::make('checked_out_to_id') + ->label(fn (Get $get): string => match ($get('checked_out_to_type')) { + Student::class => 'Select Student', + Prospect::class => 'Select Prospect', + }) + ->visible(fn (Get $get): bool => filled($get('checked_out_to_type'))) + ->getSearchResultsUsing(function (string $search, Get $get) { + return match ($get('checked_out_to_type')) { + Student::class => Student::where('full_name', 'like', "%{$search}%")->pluck('full_name', 'sisid')->toArray(), + Prospect::class => Prospect::where('full_name', 'like', "%{$search}%")->pluck('full_name', 'id')->toArray(), + }; + }) + ->searchable() + ->required(), + Textarea::make('notes') + ->autofocus(), + DateTimePicker::make('expected_check_in_at') + ->label('Expected Return Date'), + ]); + + $this->action(function (array $data): void { + /** @var Asset $asset */ + $asset = $this->getRecord(); + + if (! $asset->isAvailable()) { + $this->failure(); + } + + $asset->checkOuts()->create([ + 'checked_out_by_type' => auth()->user()?->getMorphClass(), + 'checked_out_by_id' => auth()->user()?->id, + 'checked_out_to_type' => (new $data['checked_out_to_type']())->getMorphClass(), + 'checked_out_to_id' => $data['checked_out_to_id'], + 'notes' => $data['notes'], + 'checked_out_at' => now(), + 'expected_check_in_at' => $data['expected_check_in_at'], + ]); + + $asset->update([ + 'status_id' => AssetStatus::checkedOut()->first()->id, + ]); + + $this->success(); + }); + } +} diff --git a/app-modules/inventory-management/src/Filament/Resources/AssetResource/Pages/ViewAsset.php b/app-modules/inventory-management/src/Filament/Resources/AssetResource/Pages/ViewAsset.php index aaaa2de57b..db278be7fb 100644 --- a/app-modules/inventory-management/src/Filament/Resources/AssetResource/Pages/ViewAsset.php +++ b/app-modules/inventory-management/src/Filament/Resources/AssetResource/Pages/ViewAsset.php @@ -41,7 +41,10 @@ use Filament\Resources\Pages\ViewRecord; use Filament\Infolists\Components\Section; use Filament\Infolists\Components\TextEntry; +use AdvisingApp\InventoryManagement\Models\Asset; use AdvisingApp\InventoryManagement\Filament\Resources\AssetResource; +use AdvisingApp\InventoryManagement\Filament\Actions\CheckInAssetHeaderAction; +use AdvisingApp\InventoryManagement\Filament\Actions\CheckOutAssetHeaderAction; class ViewAsset extends ViewRecord { @@ -71,6 +74,20 @@ protected function getHeaderActions(): array { return [ EditAction::make(), + CheckOutAssetHeaderAction::make('check-out') + ->visible(function () { + /** @var Asset $asset */ + $asset = $this->getRecord(); + + return $asset->isAvailable(); + }), + CheckInAssetHeaderAction::make('check-in') + ->visible(function () { + /** @var Asset $asset */ + $asset = $this->getRecord(); + + return $asset->isCheckedOut(); + }), ]; } } diff --git a/app-modules/inventory-management/src/Filament/Resources/AssetStatusResource/Pages/CreateAssetStatus.php b/app-modules/inventory-management/src/Filament/Resources/AssetStatusResource/Pages/CreateAssetStatus.php index 8e2facb1c2..62e4601954 100644 --- a/app-modules/inventory-management/src/Filament/Resources/AssetStatusResource/Pages/CreateAssetStatus.php +++ b/app-modules/inventory-management/src/Filament/Resources/AssetStatusResource/Pages/CreateAssetStatus.php @@ -37,8 +37,10 @@ namespace AdvisingApp\InventoryManagement\Filament\Resources\AssetStatusResource\Pages; use Filament\Forms\Form; +use Filament\Forms\Components\Select; use Filament\Forms\Components\TextInput; use Filament\Resources\Pages\CreateRecord; +use AdvisingApp\InventoryManagement\Enums\SystemAssetStatusClassification; use AdvisingApp\InventoryManagement\Filament\Resources\AssetStatusResource; class CreateAssetStatus extends CreateRecord @@ -51,6 +53,10 @@ public function form(Form $form): Form ->schema([ TextInput::make('name') ->required(), + Select::make('classification') + ->options(SystemAssetStatusClassification::class) + ->enum(SystemAssetStatusClassification::class) + ->required(), ]); } } diff --git a/app-modules/inventory-management/src/Filament/Resources/AssetStatusResource/Pages/ListAssetStatuses.php b/app-modules/inventory-management/src/Filament/Resources/AssetStatusResource/Pages/ListAssetStatuses.php index a67d22af3f..123fa8d625 100644 --- a/app-modules/inventory-management/src/Filament/Resources/AssetStatusResource/Pages/ListAssetStatuses.php +++ b/app-modules/inventory-management/src/Filament/Resources/AssetStatusResource/Pages/ListAssetStatuses.php @@ -57,6 +57,9 @@ public function table(Table $table): Table TextColumn::make('name') ->searchable() ->sortable(), + TextColumn::make('classification') + ->searchable() + ->sortable(), ]) ->filters([ ]) diff --git a/app-modules/inventory-management/src/Filament/Resources/AssetStatusResource/Pages/ViewAssetStatus.php b/app-modules/inventory-management/src/Filament/Resources/AssetStatusResource/Pages/ViewAssetStatus.php index ed06f374c8..7eb133e489 100644 --- a/app-modules/inventory-management/src/Filament/Resources/AssetStatusResource/Pages/ViewAssetStatus.php +++ b/app-modules/inventory-management/src/Filament/Resources/AssetStatusResource/Pages/ViewAssetStatus.php @@ -54,6 +54,7 @@ public function infolist(Infolist $infolist): Infolist Section::make() ->schema([ TextEntry::make('name'), + TextEntry::make('classification'), ]), ]); } diff --git a/app-modules/inventory-management/src/Models/Asset.php b/app-modules/inventory-management/src/Models/Asset.php index a2d9dca12d..d2723972ea 100644 --- a/app-modules/inventory-management/src/Models/Asset.php +++ b/app-modules/inventory-management/src/Models/Asset.php @@ -38,13 +38,20 @@ use App\Models\BaseModel; use OwenIt\Auditing\Contracts\Auditable; +use Illuminate\Database\Eloquent\SoftDeletes; +use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\BelongsTo; use AdvisingApp\Audit\Models\Concerns\Auditable as AuditableTrait; +use AdvisingApp\InventoryManagement\Enums\SystemAssetStatusClassification; +/** + * @mixin IdeHelperAsset + */ class Asset extends BaseModel implements Auditable { use AuditableTrait; + use SoftDeletes; protected $fillable = [ 'description', @@ -75,4 +82,43 @@ public function maintenanceActivities(): HasMany { return $this->hasMany(MaintenanceActivity::class, 'asset_id'); } + + public function checkOuts(): HasMany + { + return $this->hasMany(AssetCheckOut::class, 'asset_id'); + } + + public function checkIns(): HasMany + { + return $this->hasMany(AssetCheckIn::class, 'asset_id'); + } + + public function latestCheckOut(): HasOne + { + return $this->hasOne(AssetCheckOut::class, 'asset_id') + ->oldest('checked_out_at'); + } + + public function latestCheckIn(): HasOne + { + return $this->hasOne(AssetCheckIn::class, 'asset_id') + ->latest('checked_in_at'); + } + + public function isAvailable(): bool + { + return $this->status->classification === SystemAssetStatusClassification::Available + && ! is_null($this->latestCheckOut?->asset_check_in_id); + } + + public function isNotAvailable(): bool + { + return ! $this->isAvailable(); + } + + public function isCheckedOut(): bool + { + return $this->status->classification === SystemAssetStatusClassification::CheckedOut + && is_null($this->latestCheckOut?->asset_check_in_id); + } } diff --git a/app-modules/inventory-management/src/Models/AssetCheckIn.php b/app-modules/inventory-management/src/Models/AssetCheckIn.php new file mode 100644 index 0000000000..cef99b06aa --- /dev/null +++ b/app-modules/inventory-management/src/Models/AssetCheckIn.php @@ -0,0 +1,93 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\InventoryManagement\Models; + +use App\Models\BaseModel; +use OwenIt\Auditing\Contracts\Auditable; +use Illuminate\Database\Eloquent\SoftDeletes; +use Illuminate\Database\Eloquent\Relations\HasOne; +use Illuminate\Database\Eloquent\Relations\MorphTo; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use AdvisingApp\Audit\Models\Concerns\Auditable as AuditableTrait; + +class AssetCheckIn extends BaseModel implements Auditable +{ + use AuditableTrait; + use SoftDeletes; + + protected $fillable = [ + 'asset_id', + 'checked_in_by_type', + 'checked_in_by_id', + 'checked_in_from_type', + 'checked_in_from_id', + 'checked_in_at', + 'notes', + ]; + + protected $casts = [ + 'checked_in_at' => 'datetime', + ]; + + public function asset(): BelongsTo + { + return $this->belongsTo(Asset::class, 'asset_id'); + } + + public function checkedInBy(): MorphTo + { + return $this->morphTo( + name: 'checked_in_by', + type: 'checked_in_by_type', + id: 'checked_in_by_id', + ); + } + + public function checkedInFrom(): MorphTo + { + return $this->morphTo( + name: 'checked_in_from', + type: 'checked_in_from_type', + id: 'checked_in_from_id', + ); + } + + public function checkOut(): HasOne + { + return $this->hasOne(AssetCheckOut::class); + } +} diff --git a/app-modules/inventory-management/src/Models/AssetCheckOut.php b/app-modules/inventory-management/src/Models/AssetCheckOut.php new file mode 100644 index 0000000000..121c9de71b --- /dev/null +++ b/app-modules/inventory-management/src/Models/AssetCheckOut.php @@ -0,0 +1,95 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\InventoryManagement\Models; + +use App\Models\BaseModel; +use OwenIt\Auditing\Contracts\Auditable; +use Illuminate\Database\Eloquent\SoftDeletes; +use Illuminate\Database\Eloquent\Relations\MorphTo; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use AdvisingApp\Audit\Models\Concerns\Auditable as AuditableTrait; + +class AssetCheckOut extends BaseModel implements Auditable +{ + use AuditableTrait; + use SoftDeletes; + + protected $fillable = [ + 'asset_id', + 'asset_check_in_id', + 'checked_out_by_type', + 'checked_out_by_id', + 'checked_out_to_type', + 'checked_out_to_id', + 'checked_out_at', + 'expected_check_in_at', + 'notes', + ]; + + protected $casts = [ + 'checked_out_at' => 'datetime', + 'expected_check_in_at' => 'datetime', + ]; + + public function asset(): BelongsTo + { + return $this->belongsTo(Asset::class, 'asset_id'); + } + + public function checkedOutBy(): MorphTo + { + return $this->morphTo( + name: 'checked_out_by', + type: 'checked_out_by_type', + id: 'checked_out_by_id', + ); + } + + public function checkedOutTo(): MorphTo + { + return $this->morphTo( + name: 'checked_out_to', + type: 'checked_out_to_type', + id: 'checked_out_to_id', + ); + } + + public function checkIn(): BelongsTo + { + return $this->belongsTo(AssetCheckIn::class); + } +} diff --git a/app-modules/inventory-management/src/Models/AssetLocation.php b/app-modules/inventory-management/src/Models/AssetLocation.php index 37c656e292..871c929e26 100644 --- a/app-modules/inventory-management/src/Models/AssetLocation.php +++ b/app-modules/inventory-management/src/Models/AssetLocation.php @@ -38,12 +38,17 @@ use App\Models\BaseModel; use OwenIt\Auditing\Contracts\Auditable; +use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\Relations\HasMany; use AdvisingApp\Audit\Models\Concerns\Auditable as AuditableTrait; +/** + * @mixin IdeHelperAssetLocation + */ class AssetLocation extends BaseModel implements Auditable { use AuditableTrait; + use SoftDeletes; protected $fillable = [ 'name', diff --git a/app-modules/inventory-management/src/Models/AssetStatus.php b/app-modules/inventory-management/src/Models/AssetStatus.php index da1000a351..85e04ca8ce 100644 --- a/app-modules/inventory-management/src/Models/AssetStatus.php +++ b/app-modules/inventory-management/src/Models/AssetStatus.php @@ -38,19 +38,40 @@ use App\Models\BaseModel; use OwenIt\Auditing\Contracts\Auditable; +use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\Relations\HasMany; use AdvisingApp\Audit\Models\Concerns\Auditable as AuditableTrait; +use AdvisingApp\InventoryManagement\Enums\SystemAssetStatusClassification; +/** + * @mixin IdeHelperAssetStatus + */ class AssetStatus extends BaseModel implements Auditable { use AuditableTrait; + use SoftDeletes; protected $fillable = [ + 'classification', 'name', ]; + protected $casts = [ + 'classification' => SystemAssetStatusClassification::class, + ]; + public function assets(): HasMany { return $this->hasMany(Asset::class, 'status_id'); } + + public function scopeAvailable(): void + { + $this->where('classification', SystemAssetStatusClassification::Available); + } + + public function scopeCheckedOut(): void + { + $this->where('classification', SystemAssetStatusClassification::CheckedOut); + } } diff --git a/app-modules/inventory-management/src/Models/AssetType.php b/app-modules/inventory-management/src/Models/AssetType.php index e00d56af4e..692f0dabdc 100644 --- a/app-modules/inventory-management/src/Models/AssetType.php +++ b/app-modules/inventory-management/src/Models/AssetType.php @@ -38,12 +38,17 @@ use App\Models\BaseModel; use OwenIt\Auditing\Contracts\Auditable; +use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\Relations\HasMany; use AdvisingApp\Audit\Models\Concerns\Auditable as AuditableTrait; +/** + * @mixin IdeHelperAssetType + */ class AssetType extends BaseModel implements Auditable { use AuditableTrait; + use SoftDeletes; protected $fillable = [ 'name', diff --git a/app-modules/inventory-management/src/Models/MaintenanceActivity.php b/app-modules/inventory-management/src/Models/MaintenanceActivity.php index 71c75c3ad5..1e5ec8ce5c 100644 --- a/app-modules/inventory-management/src/Models/MaintenanceActivity.php +++ b/app-modules/inventory-management/src/Models/MaintenanceActivity.php @@ -38,13 +38,18 @@ use App\Models\BaseModel; use OwenIt\Auditing\Contracts\Auditable; +use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\Relations\BelongsTo; use AdvisingApp\Audit\Models\Concerns\Auditable as AuditableTrait; use AdvisingApp\InventoryManagement\Enums\MaintenanceActivityStatus; +/** + * @mixin IdeHelperMaintenanceActivity + */ class MaintenanceActivity extends BaseModel implements Auditable { use AuditableTrait; + use SoftDeletes; protected $fillable = [ 'asset_id', diff --git a/app-modules/inventory-management/src/Models/MaintenanceProvider.php b/app-modules/inventory-management/src/Models/MaintenanceProvider.php index c319b8eec9..6acc6b5019 100644 --- a/app-modules/inventory-management/src/Models/MaintenanceProvider.php +++ b/app-modules/inventory-management/src/Models/MaintenanceProvider.php @@ -38,12 +38,17 @@ use App\Models\BaseModel; use OwenIt\Auditing\Contracts\Auditable; +use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\Relations\HasMany; use AdvisingApp\Audit\Models\Concerns\Auditable as AuditableTrait; +/** + * @mixin IdeHelperMaintenanceProvider + */ class MaintenanceProvider extends BaseModel implements Auditable { use AuditableTrait; + use SoftDeletes; protected $fillable = [ 'name', diff --git a/app-modules/inventory-management/src/Observers/AssetCheckInObserver.php b/app-modules/inventory-management/src/Observers/AssetCheckInObserver.php new file mode 100644 index 0000000000..6909116d0b --- /dev/null +++ b/app-modules/inventory-management/src/Observers/AssetCheckInObserver.php @@ -0,0 +1,49 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\InventoryManagement\Observers; + +use AdvisingApp\InventoryManagement\Models\AssetCheckIn; + +class AssetCheckInObserver +{ + public function created(AssetCheckIn $checkIn): void + { + $checkIn->asset->latestCheckOut->update([ + 'asset_check_in_id' => $checkIn->id, + ]); + } +} diff --git a/app-modules/inventory-management/src/Policies/AssetCheckInPolicy.php b/app-modules/inventory-management/src/Policies/AssetCheckInPolicy.php new file mode 100644 index 0000000000..9e57d18e83 --- /dev/null +++ b/app-modules/inventory-management/src/Policies/AssetCheckInPolicy.php @@ -0,0 +1,100 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\InventoryManagement\Policies; + +use App\Models\Authenticatable; +use Illuminate\Auth\Access\Response; +use AdvisingApp\InventoryManagement\Models\AssetCheckIn; + +class AssetCheckInPolicy +{ + public function viewAny(Authenticatable $authenticatable): Response + { + return $authenticatable->canOrElse( + abilities: 'asset_check_in.view-any', + denyResponse: 'You do not have permission to view asset check ins.' + ); + } + + public function view(Authenticatable $authenticatable, AssetCheckIn $assetCheckIn): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_check_in.*.view', "asset_check_in.{$assetCheckIn->id}.view"], + denyResponse: 'You do not have permission to view this asset check in.' + ); + } + + public function create(Authenticatable $authenticatable): Response + { + return $authenticatable->canOrElse( + abilities: 'asset_check_in.create', + denyResponse: 'You do not have permission to create asset check ins.' + ); + } + + public function update(Authenticatable $authenticatable, AssetCheckIn $assetCheckIn): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_check_in.*.update', "asset_check_in.{$assetCheckIn->id}.update"], + denyResponse: 'You do not have permission to update this asset check in.' + ); + } + + public function delete(Authenticatable $authenticatable, AssetCheckIn $assetCheckIn): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_check_in.*.delete', "asset_check_in.{$assetCheckIn->id}.delete"], + denyResponse: 'You do not have permission to delete this asset check in.' + ); + } + + public function restore(Authenticatable $authenticatable, AssetCheckIn $assetCheckIn): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_check_in.*.restore', "asset_check_in.{$assetCheckIn->id}.restore"], + denyResponse: 'You do not have permission to restore this asset check in.' + ); + } + + public function forceDelete(Authenticatable $authenticatable, AssetCheckIn $assetCheckIn): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_check_in.*.force-delete', "asset_check_in.{$assetCheckIn->id}.force-delete"], + denyResponse: 'You do not have permission to permanently delete this asset check in.' + ); + } +} diff --git a/app-modules/inventory-management/src/Policies/AssetCheckOutPolicy.php b/app-modules/inventory-management/src/Policies/AssetCheckOutPolicy.php new file mode 100644 index 0000000000..cd227de8ca --- /dev/null +++ b/app-modules/inventory-management/src/Policies/AssetCheckOutPolicy.php @@ -0,0 +1,100 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\InventoryManagement\Policies; + +use App\Models\Authenticatable; +use Illuminate\Auth\Access\Response; +use AdvisingApp\InventoryManagement\Models\AssetCheckOut; + +class AssetCheckOutPolicy +{ + public function viewAny(Authenticatable $authenticatable): Response + { + return $authenticatable->canOrElse( + abilities: 'asset_check_out.view-any', + denyResponse: 'You do not have permission to view asset check outs.' + ); + } + + public function view(Authenticatable $authenticatable, AssetCheckOut $assetCheckOut): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_check_out.*.view', "asset_check_out.{$assetCheckOut->id}.view"], + denyResponse: 'You do not have permission to view this asset check out.' + ); + } + + public function create(Authenticatable $authenticatable): Response + { + return $authenticatable->canOrElse( + abilities: 'asset_check_out.create', + denyResponse: 'You do not have permission to create asset check outs.' + ); + } + + public function update(Authenticatable $authenticatable, AssetCheckOut $assetCheckOut): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_check_out.*.update', "asset_check_out.{$assetCheckOut->id}.update"], + denyResponse: 'You do not have permission to update this asset check out.' + ); + } + + public function delete(Authenticatable $authenticatable, AssetCheckOut $assetCheckOut): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_check_out.*.delete', "asset_check_out.{$assetCheckOut->id}.delete"], + denyResponse: 'You do not have permission to delete this asset check out.' + ); + } + + public function restore(Authenticatable $authenticatable, AssetCheckOut $assetCheckOut): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_check_out.*.restore', "asset_check_out.{$assetCheckOut->id}.restore"], + denyResponse: 'You do not have permission to restore this asset check out.' + ); + } + + public function forceDelete(Authenticatable $authenticatable, AssetCheckOut $assetCheckOut): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_check_out.*.force-delete', "asset_check_out.{$assetCheckOut->id}.force-delete"], + denyResponse: 'You do not have permission to permanently delete this asset check out.' + ); + } +} diff --git a/app-modules/inventory-management/src/Policies/AssetLocationPolicy.php b/app-modules/inventory-management/src/Policies/AssetLocationPolicy.php new file mode 100644 index 0000000000..f6500dc256 --- /dev/null +++ b/app-modules/inventory-management/src/Policies/AssetLocationPolicy.php @@ -0,0 +1,100 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\InventoryManagement\Policies; + +use App\Models\Authenticatable; +use Illuminate\Auth\Access\Response; +use AdvisingApp\InventoryManagement\Models\AssetLocation; + +class AssetLocationPolicy +{ + public function viewAny(Authenticatable $authenticatable): Response + { + return $authenticatable->canOrElse( + abilities: 'asset_location.view-any', + denyResponse: 'You do not have permission to view asset locations.' + ); + } + + public function view(Authenticatable $authenticatable, AssetLocation $assetLocation): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_location.*.view', "asset_location.{$assetLocation->id}.view"], + denyResponse: 'You do not have permission to view this asset location.' + ); + } + + public function create(Authenticatable $authenticatable): Response + { + return $authenticatable->canOrElse( + abilities: 'asset_location.create', + denyResponse: 'You do not have permission to create asset locations.' + ); + } + + public function update(Authenticatable $authenticatable, AssetLocation $assetLocation): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_location.*.update', "asset_location.{$assetLocation->id}.update"], + denyResponse: 'You do not have permission to update this asset location.' + ); + } + + public function delete(Authenticatable $authenticatable, AssetLocation $assetLocation): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_location.*.delete', "asset_location.{$assetLocation->id}.delete"], + denyResponse: 'You do not have permission to delete this asset location.' + ); + } + + public function restore(Authenticatable $authenticatable, AssetLocation $assetLocation): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_location.*.restore', "asset_location.{$assetLocation->id}.restore"], + denyResponse: 'You do not have permission to restore this asset location.' + ); + } + + public function forceDelete(Authenticatable $authenticatable, AssetLocation $assetLocation): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_location.*.force-delete', "asset_location.{$assetLocation->id}.force-delete"], + denyResponse: 'You do not have permission to permanently delete this asset location.' + ); + } +} diff --git a/app-modules/inventory-management/src/Policies/AssetPolicy.php b/app-modules/inventory-management/src/Policies/AssetPolicy.php new file mode 100644 index 0000000000..ec0b8e5140 --- /dev/null +++ b/app-modules/inventory-management/src/Policies/AssetPolicy.php @@ -0,0 +1,100 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\InventoryManagement\Policies; + +use App\Models\Authenticatable; +use Illuminate\Auth\Access\Response; +use AdvisingApp\InventoryManagement\Models\Asset; + +class AssetPolicy +{ + public function viewAny(Authenticatable $authenticatable): Response + { + return $authenticatable->canOrElse( + abilities: 'asset.view-any', + denyResponse: 'You do not have permission to view assets.' + ); + } + + public function view(Authenticatable $authenticatable, Asset $asset): Response + { + return $authenticatable->canOrElse( + abilities: ['asset.*.view', "asset.{$asset->id}.view"], + denyResponse: 'You do not have permission to view this asset.' + ); + } + + public function create(Authenticatable $authenticatable): Response + { + return $authenticatable->canOrElse( + abilities: 'asset.create', + denyResponse: 'You do not have permission to create assets.' + ); + } + + public function update(Authenticatable $authenticatable, Asset $asset): Response + { + return $authenticatable->canOrElse( + abilities: ['asset.*.update', "asset.{$asset->id}.update"], + denyResponse: 'You do not have permission to update this asset.' + ); + } + + public function delete(Authenticatable $authenticatable, Asset $asset): Response + { + return $authenticatable->canOrElse( + abilities: ['asset.*.delete', "asset.{$asset->id}.delete"], + denyResponse: 'You do not have permission to delete this asset.' + ); + } + + public function restore(Authenticatable $authenticatable, Asset $asset): Response + { + return $authenticatable->canOrElse( + abilities: ['asset.*.restore', "asset.{$asset->id}.restore"], + denyResponse: 'You do not have permission to restore this asset.' + ); + } + + public function forceDelete(Authenticatable $authenticatable, Asset $asset): Response + { + return $authenticatable->canOrElse( + abilities: ['asset.*.force-delete', "asset.{$asset->id}.force-delete"], + denyResponse: 'You do not have permission to permanently delete this asset.' + ); + } +} diff --git a/app-modules/inventory-management/src/Policies/AssetStatusPolicy.php b/app-modules/inventory-management/src/Policies/AssetStatusPolicy.php new file mode 100644 index 0000000000..1e973501b9 --- /dev/null +++ b/app-modules/inventory-management/src/Policies/AssetStatusPolicy.php @@ -0,0 +1,100 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\InventoryManagement\Policies; + +use App\Models\Authenticatable; +use Illuminate\Auth\Access\Response; +use AdvisingApp\InventoryManagement\Models\AssetStatus; + +class AssetStatusPolicy +{ + public function viewAny(Authenticatable $authenticatable): Response + { + return $authenticatable->canOrElse( + abilities: 'asset_status.view-any', + denyResponse: 'You do not have permission to view asset statuses.' + ); + } + + public function view(Authenticatable $authenticatable, AssetStatus $assetStatus): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_status.*.view', "asset_status.{$assetStatus->id}.view"], + denyResponse: 'You do not have permission to view this asset status.' + ); + } + + public function create(Authenticatable $authenticatable): Response + { + return $authenticatable->canOrElse( + abilities: 'asset_status.create', + denyResponse: 'You do not have permission to create asset statuses.' + ); + } + + public function update(Authenticatable $authenticatable, AssetStatus $assetStatus): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_status.*.update', "asset_status.{$assetStatus->id}.update"], + denyResponse: 'You do not have permission to update this asset status.' + ); + } + + public function delete(Authenticatable $authenticatable, AssetStatus $assetStatus): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_status.*.delete', "asset_status.{$assetStatus->id}.delete"], + denyResponse: 'You do not have permission to delete this asset status.' + ); + } + + public function restore(Authenticatable $authenticatable, AssetStatus $assetStatus): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_status.*.restore', "asset_status.{$assetStatus->id}.restore"], + denyResponse: 'You do not have permission to restore this asset status.' + ); + } + + public function forceDelete(Authenticatable $authenticatable, AssetStatus $assetStatus): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_status.*.force-delete', "asset_status.{$assetStatus->id}.force-delete"], + denyResponse: 'You do not have permission to permanently delete this asset status.' + ); + } +} diff --git a/app-modules/inventory-management/src/Policies/AssetTypePolicy.php b/app-modules/inventory-management/src/Policies/AssetTypePolicy.php new file mode 100644 index 0000000000..952f9140ad --- /dev/null +++ b/app-modules/inventory-management/src/Policies/AssetTypePolicy.php @@ -0,0 +1,100 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\InventoryManagement\Policies; + +use App\Models\Authenticatable; +use Illuminate\Auth\Access\Response; +use AdvisingApp\InventoryManagement\Models\AssetType; + +class AssetTypePolicy +{ + public function viewAny(Authenticatable $authenticatable): Response + { + return $authenticatable->canOrElse( + abilities: 'asset_type.view-any', + denyResponse: 'You do not have permission to view asset types.' + ); + } + + public function view(Authenticatable $authenticatable, AssetType $assetType): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_type.*.view', "asset_type.{$assetType->id}.view"], + denyResponse: 'You do not have permission to view this asset type.' + ); + } + + public function create(Authenticatable $authenticatable): Response + { + return $authenticatable->canOrElse( + abilities: 'asset_type.create', + denyResponse: 'You do not have permission to create asset types.' + ); + } + + public function update(Authenticatable $authenticatable, AssetType $assetType): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_type.*.update', "asset_type.{$assetType->id}.update"], + denyResponse: 'You do not have permission to update this asset type.' + ); + } + + public function delete(Authenticatable $authenticatable, AssetType $assetType): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_type.*.delete', "asset_type.{$assetType->id}.delete"], + denyResponse: 'You do not have permission to delete this asset type.' + ); + } + + public function restore(Authenticatable $authenticatable, AssetType $assetType): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_type.*.restore', "asset_type.{$assetType->id}.restore"], + denyResponse: 'You do not have permission to restore this asset type.' + ); + } + + public function forceDelete(Authenticatable $authenticatable, AssetType $assetType): Response + { + return $authenticatable->canOrElse( + abilities: ['asset_type.*.force-delete', "asset_type.{$assetType->id}.force-delete"], + denyResponse: 'You do not have permission to permanently delete this asset type.' + ); + } +} diff --git a/app-modules/inventory-management/src/Policies/MaintenanceActivityPolicy.php b/app-modules/inventory-management/src/Policies/MaintenanceActivityPolicy.php new file mode 100644 index 0000000000..fe5911d6c3 --- /dev/null +++ b/app-modules/inventory-management/src/Policies/MaintenanceActivityPolicy.php @@ -0,0 +1,100 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\InventoryManagement\Policies; + +use App\Models\Authenticatable; +use Illuminate\Auth\Access\Response; +use AdvisingApp\InventoryManagement\Models\MaintenanceActivity; + +class MaintenanceActivityPolicy +{ + public function viewAny(Authenticatable $authenticatable): Response + { + return $authenticatable->canOrElse( + abilities: 'maintenance_activity.view-any', + denyResponse: 'You do not have permission to view maintenance activities.' + ); + } + + public function view(Authenticatable $authenticatable, MaintenanceActivity $maintenanceActivity): Response + { + return $authenticatable->canOrElse( + abilities: ['maintenance_activity.*.view', "maintenance_activity.{$maintenanceActivity->id}.view"], + denyResponse: 'You do not have permission to view this maintenance activity.' + ); + } + + public function create(Authenticatable $authenticatable): Response + { + return $authenticatable->canOrElse( + abilities: 'maintenance_activity.create', + denyResponse: 'You do not have permission to create maintenance activities.' + ); + } + + public function update(Authenticatable $authenticatable, MaintenanceActivity $maintenanceActivity): Response + { + return $authenticatable->canOrElse( + abilities: ['maintenance_activity.*.update', "maintenance_activity.{$maintenanceActivity->id}.update"], + denyResponse: 'You do not have permission to update this maintenance activity.' + ); + } + + public function delete(Authenticatable $authenticatable, MaintenanceActivity $maintenanceActivity): Response + { + return $authenticatable->canOrElse( + abilities: ['maintenance_activity.*.delete', "maintenance_activity.{$maintenanceActivity->id}.delete"], + denyResponse: 'You do not have permission to delete this maintenance activity.' + ); + } + + public function restore(Authenticatable $authenticatable, MaintenanceActivity $maintenanceActivity): Response + { + return $authenticatable->canOrElse( + abilities: ['maintenance_activity.*.restore', "maintenance_activity.{$maintenanceActivity->id}.restore"], + denyResponse: 'You do not have permission to restore this maintenance activity.' + ); + } + + public function forceDelete(Authenticatable $authenticatable, MaintenanceActivity $maintenanceActivity): Response + { + return $authenticatable->canOrElse( + abilities: ['maintenance_activity.*.force-delete', "maintenance_activity.{$maintenanceActivity->id}.force-delete"], + denyResponse: 'You do not have permission to permanently delete this maintenance activity.' + ); + } +} diff --git a/app-modules/inventory-management/src/Policies/MaintenanceProviderPolicy.php b/app-modules/inventory-management/src/Policies/MaintenanceProviderPolicy.php new file mode 100644 index 0000000000..fab3fb32a0 --- /dev/null +++ b/app-modules/inventory-management/src/Policies/MaintenanceProviderPolicy.php @@ -0,0 +1,100 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\InventoryManagement\Policies; + +use App\Models\Authenticatable; +use Illuminate\Auth\Access\Response; +use AdvisingApp\InventoryManagement\Models\MaintenanceProvider; + +class MaintenanceProviderPolicy +{ + public function viewAny(Authenticatable $authenticatable): Response + { + return $authenticatable->canOrElse( + abilities: 'maintenance_provider.view-any', + denyResponse: 'You do not have permission to view maintenance providers.' + ); + } + + public function view(Authenticatable $authenticatable, MaintenanceProvider $maintenanceProvider): Response + { + return $authenticatable->canOrElse( + abilities: ['maintenance_provider.*.view', "maintenance_provider.{$maintenanceProvider->id}.view"], + denyResponse: 'You do not have permission to view this maintenance provider.' + ); + } + + public function create(Authenticatable $authenticatable): Response + { + return $authenticatable->canOrElse( + abilities: 'maintenance_provider.create', + denyResponse: 'You do not have permission to create maintenance providers.' + ); + } + + public function update(Authenticatable $authenticatable, MaintenanceProvider $maintenanceProvider): Response + { + return $authenticatable->canOrElse( + abilities: ['maintenance_provider.*.update', "maintenance_provider.{$maintenanceProvider->id}.update"], + denyResponse: 'You do not have permission to update this maintenance provider.' + ); + } + + public function delete(Authenticatable $authenticatable, MaintenanceProvider $maintenanceProvider): Response + { + return $authenticatable->canOrElse( + abilities: ['maintenance_provider.*.delete', "maintenance_provider.{$maintenanceProvider->id}.delete"], + denyResponse: 'You do not have permission to delete this maintenance provider.' + ); + } + + public function restore(Authenticatable $authenticatable, MaintenanceProvider $maintenanceProvider): Response + { + return $authenticatable->canOrElse( + abilities: ['maintenance_provider.*.restore', "maintenance_provider.{$maintenanceProvider->id}.restore"], + denyResponse: 'You do not have permission to restore this maintenance provider.' + ); + } + + public function forceDelete(Authenticatable $authenticatable, MaintenanceProvider $maintenanceProvider): Response + { + return $authenticatable->canOrElse( + abilities: ['maintenance_provider.*.force-delete', "maintenance_provider.{$maintenanceProvider->id}.force-delete"], + denyResponse: 'You do not have permission to permanently delete this maintenance provider.' + ); + } +} diff --git a/app-modules/inventory-management/src/Providers/InventoryManagementServiceProvider.php b/app-modules/inventory-management/src/Providers/InventoryManagementServiceProvider.php index ee84ace5b0..bed4974244 100644 --- a/app-modules/inventory-management/src/Providers/InventoryManagementServiceProvider.php +++ b/app-modules/inventory-management/src/Providers/InventoryManagementServiceProvider.php @@ -43,11 +43,14 @@ use AdvisingApp\InventoryManagement\Models\AssetType; use AdvisingApp\InventoryManagement\Models\AssetStatus; use AdvisingApp\Authorization\AuthorizationRoleRegistry; +use AdvisingApp\InventoryManagement\Models\AssetCheckIn; +use AdvisingApp\InventoryManagement\Models\AssetCheckOut; use AdvisingApp\InventoryManagement\Models\AssetLocation; use AdvisingApp\Authorization\AuthorizationPermissionRegistry; use AdvisingApp\InventoryManagement\InventoryManagementPlugin; use AdvisingApp\InventoryManagement\Models\MaintenanceActivity; use AdvisingApp\InventoryManagement\Models\MaintenanceProvider; +use AdvisingApp\InventoryManagement\Observers\AssetCheckInObserver; class InventoryManagementServiceProvider extends ServiceProvider { @@ -59,6 +62,8 @@ public function register() public function boot() { Relation::morphMap([ + 'asset_check_in' => AssetCheckIn::class, + 'asset_check_out' => AssetCheckOut::class, 'asset_location' => AssetLocation::class, 'asset_status' => AssetStatus::class, 'asset_type' => AssetType::class, @@ -67,9 +72,16 @@ public function boot() 'maintenance_provider' => MaintenanceProvider::class, ]); + $this->registerObservers(); + $this->registerRolesAndPermissions(); } + public function registerObservers(): void + { + AssetCheckIn::observe(AssetCheckInObserver::class); + } + protected function registerRolesAndPermissions() { $permissionRegistry = app(AuthorizationPermissionRegistry::class); diff --git a/app-modules/meeting-center/database/migrations/2023_12_27_194215_create_event_registration_forms_table.php b/app-modules/meeting-center/database/migrations/2023_12_27_194215_create_event_registration_forms_table.php new file mode 100644 index 0000000000..8571656d00 --- /dev/null +++ b/app-modules/meeting-center/database/migrations/2023_12_27_194215_create_event_registration_forms_table.php @@ -0,0 +1,60 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +use Illuminate\Support\Facades\Schema; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +return new class () extends Migration { + public function up(): void + { + Schema::create('event_registration_forms', function (Blueprint $table) { + $table->uuid('id')->primary(); + + $table->foreignUuid('event_id')->constrained('events')->cascadeOnDelete(); + $table->boolean('embed_enabled')->default(false); + $table->json('allowed_domains')->nullable(); + $table->string('primary_color')->nullable(); + $table->string('rounding')->nullable(); + $table->boolean('is_wizard')->default(false); + $table->boolean('recaptcha_enabled')->default(false); + $table->json('content')->nullable(); + + $table->timestamps(); + $table->softDeletes(); + }); + } +}; diff --git a/app-modules/meeting-center/database/migrations/2023_12_27_194216_create_event_attendees_table.php b/app-modules/meeting-center/database/migrations/2023_12_27_194216_create_event_attendees_table.php new file mode 100644 index 0000000000..2bcee55835 --- /dev/null +++ b/app-modules/meeting-center/database/migrations/2023_12_27_194216_create_event_attendees_table.php @@ -0,0 +1,56 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +use Illuminate\Support\Facades\Schema; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +return new class () extends Migration { + public function up(): void + { + Schema::create('event_attendees', function (Blueprint $table) { + $table->uuid('id')->primary(); + + $table->string('status'); + $table->string('email'); + $table->foreignUuid('event_id')->constrained('events')->cascadeOnDelete(); + + $table->timestamps(); + + $table->unique(['email', 'event_id']); + }); + } +}; diff --git a/app-modules/meeting-center/database/migrations/2023_12_27_194217_create_event_attendee_entities_table.php b/app-modules/meeting-center/database/migrations/2023_12_27_194217_create_event_attendee_entities_table.php new file mode 100644 index 0000000000..45532122f7 --- /dev/null +++ b/app-modules/meeting-center/database/migrations/2023_12_27_194217_create_event_attendee_entities_table.php @@ -0,0 +1,52 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +use Illuminate\Support\Facades\Schema; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +return new class () extends Migration { + public function up(): void + { + Schema::create('event_attendees_entities', function (Blueprint $table) { + $table->string('entity_id'); + $table->string('entity_type'); + $table->foreignUuid('event_attendee_id')->constrained('event_attendees')->cascadeOnDelete(); + + $table->unique(['entity_id', 'entity_type', 'event_attendee_id']); + }); + } +}; diff --git a/app-modules/meeting-center/database/migrations/2023_12_27_194226_create_event_registration_form_steps_table.php b/app-modules/meeting-center/database/migrations/2023_12_27_194226_create_event_registration_form_steps_table.php new file mode 100644 index 0000000000..bae9ad05b1 --- /dev/null +++ b/app-modules/meeting-center/database/migrations/2023_12_27_194226_create_event_registration_form_steps_table.php @@ -0,0 +1,55 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +use Illuminate\Support\Facades\Schema; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +return new class () extends Migration { + public function up(): void + { + Schema::create('event_registration_form_steps', function (Blueprint $table) { + $table->uuid('id')->primary(); + + $table->text('label'); + $table->json('content')->nullable(); + $table->foreignUuid('form_id')->constrained('event_registration_forms')->cascadeOnDelete(); + $table->integer('sort'); + + $table->timestamps(); + }); + } +}; diff --git a/app-modules/meeting-center/database/migrations/2023_12_27_194227_create_event_registration_form_fields_table.php b/app-modules/meeting-center/database/migrations/2023_12_27_194227_create_event_registration_form_fields_table.php new file mode 100644 index 0000000000..4b8f20c26a --- /dev/null +++ b/app-modules/meeting-center/database/migrations/2023_12_27_194227_create_event_registration_form_fields_table.php @@ -0,0 +1,58 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +use Illuminate\Support\Facades\Schema; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +return new class () extends Migration { + public function up(): void + { + Schema::create('event_registration_form_fields', function (Blueprint $table) { + $table->uuid('id')->primary(); + + $table->text('label'); + $table->text('type'); + $table->boolean('is_required'); + $table->json('config'); + + $table->foreignUuid('form_id')->constrained('event_registration_forms')->cascadeOnDelete(); + $table->foreignUuid('step_id')->nullable()->constrained('event_registration_form_steps')->cascadeOnDelete(); + + $table->timestamps(); + }); + } +}; diff --git a/app-modules/meeting-center/database/migrations/2023_12_27_194228_create_event_registration_form_authentications_table.php b/app-modules/meeting-center/database/migrations/2023_12_27_194228_create_event_registration_form_authentications_table.php new file mode 100644 index 0000000000..31216c9ba4 --- /dev/null +++ b/app-modules/meeting-center/database/migrations/2023_12_27_194228_create_event_registration_form_authentications_table.php @@ -0,0 +1,54 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +use Illuminate\Support\Facades\Schema; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +return new class () extends Migration { + public function up(): void + { + Schema::create('event_registration_form_authentications', function (Blueprint $table) { + $table->uuid('id')->primary(); + + $table->foreignUuid('event_attendee_id')->constrained('event_attendees')->cascadeOnDelete(); + $table->string('code')->nullable(); + $table->foreignUuid('form_id')->constrained('event_registration_forms')->cascadeOnDelete(); + + $table->timestamps(); + }); + } +}; diff --git a/app-modules/meeting-center/database/migrations/2023_12_27_194229_create_event_registration_form_submissions_table.php b/app-modules/meeting-center/database/migrations/2023_12_27_194229_create_event_registration_form_submissions_table.php new file mode 100644 index 0000000000..af7df1dc37 --- /dev/null +++ b/app-modules/meeting-center/database/migrations/2023_12_27_194229_create_event_registration_form_submissions_table.php @@ -0,0 +1,56 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +use Illuminate\Support\Facades\Schema; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +return new class () extends Migration { + public function up(): void + { + Schema::create('event_registration_form_submissions', function (Blueprint $table) { + $table->uuid('id')->primary(); + + $table->foreignUuid('form_id')->constrained('event_registration_forms')->cascadeOnDelete(); + $table->foreignUuid('event_attendee_id')->constrained('event_attendees')->cascadeOnDelete(); + $table->string('attendee_status'); + $table->timestamp('submitted_at')->nullable(); + + $table->timestamps(); + $table->softDeletes(); + }); + } +}; diff --git a/app-modules/meeting-center/database/migrations/2023_12_27_194230_create_survey_field_submission_table.php b/app-modules/meeting-center/database/migrations/2023_12_27_194230_create_survey_field_submission_table.php new file mode 100644 index 0000000000..d5b0f6c326 --- /dev/null +++ b/app-modules/meeting-center/database/migrations/2023_12_27_194230_create_survey_field_submission_table.php @@ -0,0 +1,54 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +use Illuminate\Support\Facades\Schema; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +return new class () extends Migration { + public function up(): void + { + Schema::create('event_registration_form_field_submission', function (Blueprint $table) { + $table->uuid('id')->primary(); + + $table->longText('response'); + $table->foreignUuid('field_id')->constrained('event_registration_form_fields')->cascadeOnDelete(); + $table->foreignUuid('submission_id')->constrained('event_registration_form_submissions')->cascadeOnDelete(); + + $table->timestamps(); + }); + } +}; diff --git a/app-modules/meeting-center/resources/views/event-registration-submission.blade.php b/app-modules/meeting-center/resources/views/event-registration-submission.blade.php new file mode 100644 index 0000000000..2756746379 --- /dev/null +++ b/app-modules/meeting-center/resources/views/event-registration-submission.blade.php @@ -0,0 +1,55 @@ +{{-- + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +--}} + +
+ @if ($submission->submissible->is_wizard) + @foreach ($submission->submissible->steps as $step) + + + {{ $step->label }} + + + + + @endforeach + @else + + @endif +
diff --git a/app-modules/meeting-center/resources/views/livewire/event-attendee-submissions-manager.blade.php b/app-modules/meeting-center/resources/views/livewire/event-attendee-submissions-manager.blade.php new file mode 100644 index 0000000000..9c8071e9c4 --- /dev/null +++ b/app-modules/meeting-center/resources/views/livewire/event-attendee-submissions-manager.blade.php @@ -0,0 +1,36 @@ +{{-- + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +--}} +
+ {{ $this->table }} +
diff --git a/app-modules/meeting-center/resources/views/livewire/render-event-registration-form.blade.php b/app-modules/meeting-center/resources/views/livewire/render-event-registration-form.blade.php new file mode 100644 index 0000000000..e6e327ca9d --- /dev/null +++ b/app-modules/meeting-center/resources/views/livewire/render-event-registration-form.blade.php @@ -0,0 +1,42 @@ +{{-- + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +--}} +@php + use AdvisingApp\Form\Actions\GenerateSubmissibleEmbedCode; +@endphp + +
+
+ {!! resolve(GenerateSubmissibleEmbedCode::class)->handle($this->event->eventRegistrationForm) !!} +
+
diff --git a/app-modules/meeting-center/routes/api.php b/app-modules/meeting-center/routes/api.php new file mode 100644 index 0000000000..1bb564f34d --- /dev/null +++ b/app-modules/meeting-center/routes/api.php @@ -0,0 +1,62 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +use AdvisingApp\MeetingCenter\Http\Controllers\EventRegistrationWidgetController; +use AdvisingApp\MeetingCenter\Http\Middleware\EnsureEventRegistrationFormIsEmbeddableAndAuthorized; + +Route::prefix('api') + ->middleware([ + 'api', + EnsureEventRegistrationFormIsEmbeddableAndAuthorized::class . ':event', + ]) + ->group(function () { + Route::prefix('event-registration') + ->name('event-registration.') + ->group(function () { + Route::get('/{event}', [EventRegistrationWidgetController::class, 'view']) + ->middleware(['signed']) + ->name('define'); + Route::post('/{event}/authenticate/request', [EventRegistrationWidgetController::class, 'requestAuthentication']) + ->middleware(['signed']) + ->name('request-authentication'); + Route::post('/{event}/authenticate/{authentication}', [EventRegistrationWidgetController::class, 'authenticate']) + ->middleware(['signed']) + ->name('authenticate'); + Route::post('/{event}/submit', [EventRegistrationWidgetController::class, 'store']) + ->middleware(['signed']) + ->name('submit'); + }); + }); diff --git a/app-modules/meeting-center/routes/web.php b/app-modules/meeting-center/routes/web.php index 796a4317ab..b5951e3f04 100644 --- a/app-modules/meeting-center/routes/web.php +++ b/app-modules/meeting-center/routes/web.php @@ -35,6 +35,7 @@ */ use AdvisingApp\MeetingCenter\Enums\CalendarProvider; +use AdvisingApp\MeetingCenter\Livewire\RenderEventRegistrationForm; use AdvisingApp\MeetingCenter\Http\Controllers\GoogleCalendarController; use AdvisingApp\MeetingCenter\Http\Controllers\OutlookCalendarController; @@ -45,3 +46,11 @@ provider_routes(CalendarProvider::Google, GoogleCalendarController::class); provider_routes(CalendarProvider::Outlook, OutlookCalendarController::class); }); + +Route::middleware('web') + ->prefix('event-registration') + ->name('event-registration.') + ->group(function () { + Route::get('/{event}/respond', RenderEventRegistrationForm::class) + ->name('show'); + }); diff --git a/app-modules/meeting-center/src/Actions/GenerateEventRegistrationFormKitSchema.php b/app-modules/meeting-center/src/Actions/GenerateEventRegistrationFormKitSchema.php new file mode 100644 index 0000000000..b9646558fb --- /dev/null +++ b/app-modules/meeting-center/src/Actions/GenerateEventRegistrationFormKitSchema.php @@ -0,0 +1,87 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\MeetingCenter\Actions; + +use AdvisingApp\Form\Models\Submissible; +use AdvisingApp\Form\Actions\GenerateFormKitSchema; + +class GenerateEventRegistrationFormKitSchema extends GenerateFormKitSchema +{ + public function __invoke(Submissible $submissible): array + { + return [ + '$cmp' => 'FormKit', + 'props' => [ + 'type' => 'form', + 'id' => 'form', + 'onSubmit' => '$submitForm', + 'plugins' => '$plugins', + 'actions' => false, + ], + 'children' => [ + [ + '$formkit' => 'radio', + 'label' => 'Will you be attending?', + 'id' => 'attending', + 'name' => 'attending', + 'options' => [ + [ + 'label' => 'Yes', + 'value' => 'yes', + ], + [ + 'label' => 'No', + 'value' => 'no', + ], + ], + 'validation' => 'required', + ], + [ + '$el' => 'div', + 'if' => '$get(attending).value === "yes"', + 'children' => $this->generateContent($submissible), + ], + [ + '$formkit' => 'submit', + 'if' => '$get(attending).value === "no"', + 'label' => 'Submit', + 'disabled' => '$get(form).state.valid !== true', + ], + ], + ]; + } +} diff --git a/app-modules/meeting-center/src/Enums/EventAttendeeStatus.php b/app-modules/meeting-center/src/Enums/EventAttendeeStatus.php new file mode 100644 index 0000000000..407f84ae5e --- /dev/null +++ b/app-modules/meeting-center/src/Enums/EventAttendeeStatus.php @@ -0,0 +1,69 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\MeetingCenter\Enums; + +use Filament\Support\Contracts\HasColor; +use Filament\Support\Contracts\HasLabel; + +enum EventAttendeeStatus: string implements HasColor, HasLabel +{ + case Invited = 'invited'; + + case Pending = 'pending'; + + case Attending = 'attending'; + + case NotAttending = 'not_attending'; + + public function getLabel(): ?string + { + return match ($this) { + self::NotAttending => 'Not Attending', + default => $this->name, + }; + } + + public function getColor(): string + { + return match ($this) { + self::Invited => 'info', + self::Pending => 'warning', + self::Attending => 'success', + self::NotAttending => 'danger', + }; + } +} diff --git a/app-modules/meeting-center/src/Filament/Resources/EventResource.php b/app-modules/meeting-center/src/Filament/Resources/EventResource.php index 57e54bee16..7f258955d0 100644 --- a/app-modules/meeting-center/src/Filament/Resources/EventResource.php +++ b/app-modules/meeting-center/src/Filament/Resources/EventResource.php @@ -37,11 +37,13 @@ namespace AdvisingApp\MeetingCenter\Filament\Resources; use Filament\Resources\Resource; +use Filament\Resources\Pages\Page; use AdvisingApp\MeetingCenter\Models\Event; use AdvisingApp\MeetingCenter\Filament\Resources\EventResource\Pages\EditEvent; use AdvisingApp\MeetingCenter\Filament\Resources\EventResource\Pages\ViewEvent; use AdvisingApp\MeetingCenter\Filament\Resources\EventResource\Pages\ListEvents; use AdvisingApp\MeetingCenter\Filament\Resources\EventResource\Pages\CreateEvent; +use AdvisingApp\MeetingCenter\Filament\Resources\EventResource\Pages\ManageEventAttendees; class EventResource extends Resource { @@ -58,6 +60,15 @@ public static function getRelations(): array return []; } + public static function getRecordSubNavigation(Page $page): array + { + return $page->generateNavigationItems([ + ViewEvent::class, + EditEvent::class, + ManageEventAttendees::class, + ]); + } + public static function getPages(): array { return [ @@ -65,6 +76,7 @@ public static function getPages(): array 'create' => CreateEvent::route('/create'), 'view' => ViewEvent::route('/{record}'), 'edit' => EditEvent::route('/{record}/edit'), + 'manage-attendees' => ManageEventAttendees::route('/{record}/manage-attendees'), ]; } } diff --git a/app-modules/meeting-center/src/Filament/Resources/EventResource/Pages/Concerns/HasSharedEventFormConfiguration.php b/app-modules/meeting-center/src/Filament/Resources/EventResource/Pages/Concerns/HasSharedEventFormConfiguration.php new file mode 100644 index 0000000000..fb5f1f5ce4 --- /dev/null +++ b/app-modules/meeting-center/src/Filament/Resources/EventResource/Pages/Concerns/HasSharedEventFormConfiguration.php @@ -0,0 +1,279 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\MeetingCenter\Filament\Resources\EventResource\Pages\Concerns; + +use App\Models\User; +use Filament\Forms\Get; +use Filament\Forms\Components\Grid; +use AdvisingApp\Form\Enums\Rounding; +use AdvisingApp\Form\Rules\IsDomain; +use App\Forms\Components\ColorSelect; +use Filament\Forms\Components\Select; +use Filament\Forms\Components\Toggle; +use Filament\Forms\Components\Section; +use FilamentTiptapEditor\TiptapEditor; +use Filament\Forms\Components\Fieldset; +use Filament\Forms\Components\Repeater; +use Filament\Forms\Components\Textarea; +use Filament\Forms\Components\Component; +use Filament\Forms\Components\TagsInput; +use Filament\Forms\Components\TextInput; +use AdvisingApp\MeetingCenter\Models\Event; +use FilamentTiptapEditor\Enums\TiptapOutput; +use Filament\Forms\Components\DateTimePicker; +use AdvisingApp\MeetingCenter\Models\EventRegistrationForm; +use AdvisingApp\Form\Filament\Blocks\FormFieldBlockRegistry; +use Illuminate\Database\Eloquent\Builder as EloquentBuilder; +use AdvisingApp\MeetingCenter\Models\EventRegistrationFormStep; +use AdvisingApp\MeetingCenter\Models\EventRegistrationFormField; +use Filament\Forms\Components\Contracts\CanEntangleWithSingularRelationships; + +trait HasSharedEventFormConfiguration +{ + public function fields(): array + { + /** @var User $user */ + $user = auth()->user(); + + return [ + TextInput::make('title') + ->string() + ->required(), + Textarea::make('description') + ->string() + ->nullable(), + TextInput::make('location') + ->string() + ->nullable(), + TextInput::make('capacity') + ->integer() + ->minValue(1) + ->nullable(), + DateTimePicker::make('starts_at') + ->timezone($user->timezone) + ->required(), + DateTimePicker::make('ends_at') + ->timezone($user->timezone) + ->required(), + Fieldset::make('Registration Form') + ->relationship('eventRegistrationForm') + ->saveRelationshipsBeforeChildrenUsing(static function (Component | CanEntangleWithSingularRelationships $component): void { + $component->getCachedExistingRecord()?->delete(); + + $relationship = $component->getRelationship(); + + $data = $component->getChildComponentContainer()->getState(shouldCallHooksBefore: false); + $data = $component->mutateRelationshipDataBeforeCreate($data); + + $relatedModel = $component->getRelatedModel(); + + $record = new $relatedModel(); + $record->fill($data); + + $relationship->save($record); + + $component->cachedExistingRecord($record); + }) + ->saveRelationshipsUsing(null) + ->schema([ + Grid::make() + ->schema([ + Toggle::make('embed_enabled') + ->label('Embed Enabled') + ->live() + ->helperText('If enabled, this form can be embedded on other websites.'), + TagsInput::make('allowed_domains') + ->label('Allowed Domains') + ->helperText('Only these domains will be allowed to embed this form.') + ->placeholder('example.com') + ->hidden(fn (Get $get) => ! $get('embed_enabled')) + ->disabled(fn (Get $get) => ! $get('embed_enabled')) + ->nestedRecursiveRules( + [ + 'string', + new IsDomain(), + ] + ), + ]) + ->columnSpanFull(), + Toggle::make('is_wizard') + ->label('Multi-step form') + ->live() + ->disabled(fn (?EventRegistrationForm $record) => $record?->submissions()->exists()), + Section::make('Fields') + ->schema([ + $this->fieldBuilder(), + ]) + ->hidden(fn (Get $get) => $get('is_wizard')) + ->disabled(fn (?EventRegistrationForm $record) => $record?->submissions()->exists()), + Repeater::make('steps') + ->schema([ + TextInput::make('label') + ->required() + ->string() + ->maxLength(255) + ->autocomplete(false) + ->columnSpanFull() + ->lazy(), + $this->fieldBuilder(), + ]) + ->addActionLabel('New step') + ->itemLabel(fn (array $state): ?string => $state['label'] ?? null) + ->visible(fn (Get $get) => $get('is_wizard')) + ->disabled(fn (?EventRegistrationForm $record) => $record?->submissions()->exists()) + ->relationship() + ->reorderable() + ->columnSpanFull(), + Section::make('Appearance') + ->schema([ + ColorSelect::make('primary_color'), + Select::make('rounding') + ->options(Rounding::class), + ]) + ->columns(), + ]), + ]; + } + + public function fieldBuilder(): TiptapEditor + { + return TiptapEditor::make('content') + ->output(TiptapOutput::Json) + ->blocks(FormFieldBlockRegistry::get()) + ->tools(['bold', 'italic', 'small', '|', 'heading', 'bullet-list', 'ordered-list', 'hr', '|', 'link', 'grid', 'blocks']) + ->placeholder('Drag blocks here to build your form') + ->hiddenLabel() + ->saveRelationshipsUsing(function (TiptapEditor $component, EventRegistrationForm | EventRegistrationFormStep $record) { + if ($component->isDisabled()) { + return; + } + + $form = $record instanceof EventRegistrationForm ? $record : $record->submissible; + $formStep = $record instanceof EventRegistrationFormStep ? $record : null; + + EventRegistrationFormField::query() + ->whereBelongsTo($form, 'submissible') + ->when($formStep, fn (EloquentBuilder $query) => $query->whereBelongsTo($formStep, 'step')) + ->delete(); + + $content = $component->decodeBlocksBeforeSave($component->getJSON(decoded: true)); + $content['content'] = $this->saveFieldsFromComponents( + $form, + $content['content'] ?? [], + $formStep, + ); + + $record->content = $content; + $record->save(); + }) + ->dehydrated(false) + ->columnSpanFull() + ->extraInputAttributes(['style' => 'min-height: 12rem;']); + } + + public function saveFieldsFromComponents(EventRegistrationForm $form, array $components, ?EventRegistrationFormStep $eventRegistrationFormStep): array + { + foreach ($components as $componentKey => $component) { + if (array_key_exists('content', $component)) { + $components[$componentKey]['content'] = $this->saveFieldsFromComponents($form, $component['content'], $eventRegistrationFormStep); + + continue; + } + + if ($component['type'] !== 'tiptapBlock') { + continue; + } + + $componentAttributes = $component['attrs'] ?? []; + + if (array_key_exists('id', $componentAttributes)) { + $id = $componentAttributes['id'] ?? null; + unset($componentAttributes['id']); + } + + if (array_key_exists('label', $componentAttributes['data'])) { + $label = $componentAttributes['data']['label'] ?? null; + unset($componentAttributes['data']['label']); + } + + if (array_key_exists('isRequired', $componentAttributes['data'])) { + $isRequired = $componentAttributes['data']['isRequired'] ?? null; + unset($componentAttributes['data']['isRequired']); + } + + /** @var EventRegistrationFormField $field */ + $field = $form->fields()->findOrNew($id ?? null); + $field->step()->associate($eventRegistrationFormStep); + $field->label = $label ?? $componentAttributes['type']; + $field->is_required = $isRequired ?? false; + $field->type = $componentAttributes['type']; + $field->config = $componentAttributes['data']; + $field->save(); + + $components[$componentKey]['attrs']['id'] = $field->id; + } + + return $components; + } + + protected function afterCreate(): void + { + $this->clearFormContentForWizard(); + } + + protected function afterSave(): void + { + $this->clearFormContentForWizard(); + } + + protected function clearFormContentForWizard(): void + { + /** @var Event $event */ + $event = $this->record; + + $form = $event->eventRegistrationForm; + + if ($form?->is_wizard) { + $form->content = null; + $form->save(); + + return; + } + + $form?->steps()->delete(); + } +} diff --git a/app-modules/meeting-center/src/Filament/Resources/EventResource/Pages/CreateEvent.php b/app-modules/meeting-center/src/Filament/Resources/EventResource/Pages/CreateEvent.php index 5fb7b12ea2..28a87776c3 100644 --- a/app-modules/meeting-center/src/Filament/Resources/EventResource/Pages/CreateEvent.php +++ b/app-modules/meeting-center/src/Filament/Resources/EventResource/Pages/CreateEvent.php @@ -36,43 +36,19 @@ namespace AdvisingApp\MeetingCenter\Filament\Resources\EventResource\Pages; -use App\Models\User; use Filament\Forms\Form; -use Filament\Forms\Components\Textarea; -use Filament\Forms\Components\TextInput; use Filament\Resources\Pages\CreateRecord; -use Filament\Forms\Components\DateTimePicker; use AdvisingApp\MeetingCenter\Filament\Resources\EventResource; +use AdvisingApp\MeetingCenter\Filament\Resources\EventResource\Pages\Concerns\HasSharedEventFormConfiguration; class CreateEvent extends CreateRecord { + use HasSharedEventFormConfiguration; + protected static string $resource = EventResource::class; public function form(Form $form): Form { - /** @var User $user */ - $user = auth()->user(); - - return $form->schema([ - TextInput::make('title') - ->string() - ->required(), - Textarea::make('description') - ->string() - ->nullable(), - TextInput::make('location') - ->string() - ->nullable(), - TextInput::make('capacity') - ->integer() - ->minValue(1) - ->nullable(), - DateTimePicker::make('starts_at') - ->timezone($user->timezone) - ->required(), - DateTimePicker::make('ends_at') - ->timezone($user->timezone) - ->required(), - ]); + return $form->schema($this->fields()); } } diff --git a/app-modules/meeting-center/src/Filament/Resources/EventResource/Pages/EditEvent.php b/app-modules/meeting-center/src/Filament/Resources/EventResource/Pages/EditEvent.php index 7a1ac857ca..7e8a652fdf 100644 --- a/app-modules/meeting-center/src/Filament/Resources/EventResource/Pages/EditEvent.php +++ b/app-modules/meeting-center/src/Filament/Resources/EventResource/Pages/EditEvent.php @@ -36,46 +36,22 @@ namespace AdvisingApp\MeetingCenter\Filament\Resources\EventResource\Pages; -use App\Models\User; use Filament\Forms\Form; use Filament\Actions\ViewAction; use Filament\Actions\DeleteAction; -use Filament\Forms\Components\Textarea; -use Filament\Forms\Components\TextInput; use Filament\Resources\Pages\EditRecord; -use Filament\Forms\Components\DateTimePicker; use AdvisingApp\MeetingCenter\Filament\Resources\EventResource; +use AdvisingApp\MeetingCenter\Filament\Resources\EventResource\Pages\Concerns\HasSharedEventFormConfiguration; class EditEvent extends EditRecord { + use HasSharedEventFormConfiguration; + protected static string $resource = EventResource::class; public function form(Form $form): Form { - /** @var User $user */ - $user = auth()->user(); - - return $form->schema([ - TextInput::make('title') - ->string() - ->required(), - Textarea::make('description') - ->string() - ->nullable(), - TextInput::make('location') - ->string() - ->nullable(), - TextInput::make('capacity') - ->integer() - ->minValue(1) - ->nullable(), - DateTimePicker::make('starts_at') - ->timezone($user->timezone) - ->required(), - DateTimePicker::make('ends_at') - ->timezone($user->timezone) - ->required(), - ]); + return $form->schema($this->fields()); } protected function getHeaderActions(): array diff --git a/app-modules/meeting-center/src/Filament/Resources/EventResource/Pages/ManageEventAttendees.php b/app-modules/meeting-center/src/Filament/Resources/EventResource/Pages/ManageEventAttendees.php new file mode 100644 index 0000000000..dc7cc511f5 --- /dev/null +++ b/app-modules/meeting-center/src/Filament/Resources/EventResource/Pages/ManageEventAttendees.php @@ -0,0 +1,128 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\MeetingCenter\Filament\Resources\EventResource\Pages; + +use Filament\Tables\Table; +use App\Filament\Columns\IdColumn; +use Filament\Tables\Actions\ViewAction; +use Filament\Tables\Columns\TextColumn; +use AdvisingApp\Prospect\Models\Prospect; +use Filament\Infolists\Components\Fieldset; +use Filament\Infolists\Components\Livewire; +use Filament\Infolists\Components\TextEntry; +use AdvisingApp\StudentDataModel\Models\Student; +use Filament\Infolists\Components\RepeatableEntry; +use Filament\Resources\Pages\ManageRelatedRecords; +use AdvisingApp\MeetingCenter\Models\EventAttendee; +use AdvisingApp\Prospect\Filament\Resources\ProspectResource; +use AdvisingApp\MeetingCenter\Filament\Resources\EventResource; +use AdvisingApp\StudentDataModel\Filament\Resources\StudentResource; + +class ManageEventAttendees extends ManageRelatedRecords +{ + protected static string $resource = EventResource::class; + + // TODO: Obsolete when there is no table, remove from Filament + protected static string $relationship = 'attendees'; + + protected static ?string $navigationLabel = 'Attendees'; + + protected static ?string $breadcrumb = 'Attendees'; + + protected static ?string $navigationIcon = 'heroicon-o-document-text'; + + public function table(Table $table): Table + { + return $table + ->columns([ + IdColumn::make(), + TextColumn::make('status') + ->badge(), + TextColumn::make('email'), + ]) + ->filters([]) + ->headerActions([]) + ->actions([ + ViewAction::make() + ->modalHeading(fn (EventAttendee $record) => $record->event->title . ' - ' . $record->email) + ->infolist(fn (EventAttendee $record): array => [ + Fieldset::make('Attendee Info') + ->schema([ + TextEntry::make('status') + ->label('Status') + ->badge(), + TextEntry::make('email') + ->label('Email address'), + ]) + ->columns(), + + Fieldset::make('Relations') + ->schema([ + RepeatableEntry::make('prospects') + ->schema([ + TextEntry::make(Prospect::displayNameKey()) + ->label('Name') + ->color('primary') + ->url(fn (Prospect $record): string => ProspectResource::getUrl('view', ['record' => $record])), + ]) + ->columns() + ->visible(fn (EventAttendee $record): bool => $record->prospects->isNotEmpty()), + RepeatableEntry::make('students') + ->schema([ + TextEntry::make(Student::displayNameKey()) + ->label('Name') + ->color('primary') + ->url(fn (Student $record): string => StudentResource::getUrl('view', ['record' => $record])), + ]) + ->columns() + ->visible(fn (EventAttendee $record): bool => $record->students->isNotEmpty()), + ]) + ->visible(fn (EventAttendee $record): bool => $record->prospects->isNotEmpty() || $record->students->isNotEmpty()) + ->columns(), + + Fieldset::make('Attendee Submissions') + ->schema([ + // TODO: Look into Livewire/Filament bug that prevents us from passing the class here, requiring that we define it in the Service Provider + // TODO: Look into bug where, without lazy load, you have to click view twice to get the modal to show + Livewire::make('event-attendee-submissions-manager')->lazy() + ->columnSpanFull(), + ]), + ]), + ]) + ->bulkActions([]); + } +} diff --git a/app-modules/meeting-center/src/Filament/Resources/EventResource/Pages/ViewEvent.php b/app-modules/meeting-center/src/Filament/Resources/EventResource/Pages/ViewEvent.php index 06d58a2b7f..be813c72a9 100644 --- a/app-modules/meeting-center/src/Filament/Resources/EventResource/Pages/ViewEvent.php +++ b/app-modules/meeting-center/src/Filament/Resources/EventResource/Pages/ViewEvent.php @@ -36,11 +36,13 @@ namespace AdvisingApp\MeetingCenter\Filament\Resources\EventResource\Pages; +use Filament\Actions\Action; use Filament\Actions\EditAction; use Filament\Infolists\Infolist; use Filament\Actions\DeleteAction; use Filament\Resources\Pages\ViewRecord; use Filament\Infolists\Components\Section; +use AdvisingApp\MeetingCenter\Models\Event; use Filament\Infolists\Components\TextEntry; use AdvisingApp\MeetingCenter\Filament\Resources\EventResource; @@ -68,6 +70,10 @@ public function infolist(Infolist $infolist): Infolist protected function getHeaderActions(): array { return [ + Action::make('view') + ->url(fn (Event $event) => route('event-registration.show', ['event' => $event])) + ->icon('heroicon-m-arrow-top-right-on-square') + ->openUrlInNewTab(), EditAction::make(), DeleteAction::make(), ]; diff --git a/app-modules/meeting-center/src/Http/Controllers/EventRegistrationWidgetController.php b/app-modules/meeting-center/src/Http/Controllers/EventRegistrationWidgetController.php new file mode 100644 index 0000000000..b1c816251e --- /dev/null +++ b/app-modules/meeting-center/src/Http/Controllers/EventRegistrationWidgetController.php @@ -0,0 +1,247 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\MeetingCenter\Http\Controllers; + +use Closure; +use Exception; +use Illuminate\Support\Str; +use Illuminate\Http\Request; +use Illuminate\Http\JsonResponse; +use Filament\Support\Colors\Color; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\URL; +use App\Http\Controllers\Controller; +use Illuminate\Support\Facades\Hash; +use Illuminate\Support\Facades\Validator; +use AdvisingApp\MeetingCenter\Models\Event; +use Illuminate\Support\Facades\Notification; +use Symfony\Component\HttpFoundation\Response; +use AdvisingApp\MeetingCenter\Models\EventAttendee; +use AdvisingApp\MeetingCenter\Enums\EventAttendeeStatus; +use AdvisingApp\Form\Actions\GenerateSubmissibleValidation; +use AdvisingApp\MeetingCenter\Models\EventRegistrationFormSubmission; +use AdvisingApp\MeetingCenter\Models\EventRegistrationFormAuthentication; +use AdvisingApp\IntegrationGoogleRecaptcha\Settings\GoogleRecaptchaSettings; +use AdvisingApp\MeetingCenter\Actions\GenerateEventRegistrationFormKitSchema; +use AdvisingApp\MeetingCenter\Notifications\AuthenticateEventRegistrationFormNotification; + +class EventRegistrationWidgetController extends Controller +{ + public function view(GenerateEventRegistrationFormKitSchema $generateSchema, Event $event): JsonResponse + { + $form = $event->eventRegistrationForm; + + return response()->json( + [ + 'name' => $form->event->title, + 'description' => $form->event->description, + 'is_authenticated' => true, + 'authentication_url' => URL::signedRoute('event-registration.request-authentication', ['event' => $event]), + 'recaptcha_enabled' => $form->recaptcha_enabled, + ...($form->recaptcha_enabled ? [ + 'recaptcha_site_key' => app(GoogleRecaptchaSettings::class)->site_key, + ] : []), + 'schema' => $generateSchema($form), + 'primary_color' => Color::all()[$form->primary_color ?? 'blue'], + 'rounding' => $form->rounding, + ], + ); + } + + public function requestAuthentication(Request $request, Event $event): JsonResponse + { + $form = $event->eventRegistrationForm; + + $data = $request->validate([ + 'email' => ['required', 'email'], + ]); + + $attendee = EventAttendee::firstOrNew( + [ + 'email' => $data['email'], + 'event_id' => $form->event_id, + ], + ); + + if (empty($attendee->status)) { + $attendee->status = EventAttendeeStatus::Pending; + } + + // TODO: When an EventAttendee is created, we should try and match it to an entity, perhaps in an observer. + $attendee->save(); + + $code = random_int(100000, 999999); + + $authentication = new EventRegistrationFormAuthentication(); + $authentication->author()->associate($attendee); + $authentication->submissible()->associate($form); + $authentication->code = Hash::make($code); + $authentication->save(); + + Notification::route('mail', $attendee->email)->notify(new AuthenticateEventRegistrationFormNotification($authentication, $code)); + + return response()->json([ + 'message' => "We've sent an authentication code to {$attendee->email}.", + 'authentication_url' => URL::signedRoute('event-registration.authenticate', [ + 'event' => $event, + 'authentication' => $authentication, + ]), + ]); + } + + public function authenticate(Request $request, Event $event, EventRegistrationFormAuthentication $authentication): JsonResponse + { + if ($authentication->isExpired()) { + return response()->json([ + 'is_expired' => true, + ]); + } + + $request->validate([ + 'code' => ['required', 'integer', 'digits:6', function (string $attribute, int $value, Closure $fail) use ($authentication) { + if (Hash::check($value, $authentication->code)) { + return; + } + + $fail('The provided code is invalid.'); + }], + ]); + + return response()->json([ + 'submission_url' => URL::signedRoute('event-registration.submit', [ + 'authentication' => $authentication, + 'event' => $authentication->submissible->event, + ]), + ]); + } + + public function store( + Request $request, + GenerateSubmissibleValidation $generateValidation, + Event $event, + ): JsonResponse { + try { + DB::beginTransaction(); + + $form = $event->eventRegistrationForm; + + $authentication = $request->query('authentication'); + + if (filled($authentication)) { + $authentication = EventRegistrationFormAuthentication::findOrFail($authentication); + } + + if ( + ($authentication?->isExpired() ?? true) + ) { + abort(Response::HTTP_UNAUTHORIZED); + } + + $validator = Validator::make( + $request->all(), + [ + 'attending' => ['required', 'in:yes,no'], + ...$request->get('attending') === 'yes' ? $generateValidation($form) : [], + ] + ); + + if ($validator->fails()) { + return response()->json( + [ + 'errors' => (object) $validator->errors(), + ], + Response::HTTP_UNPROCESSABLE_ENTITY + ); + } + + /** @var EventRegistrationFormSubmission $submission */ + $submission = $form->submissions()->make(); + + $submission->author()->associate($authentication->author); + + $authentication->delete(); + + $submission->submitted_at = now(); + + $submission->attendee_status = $request->get('attending') === 'yes' ? EventAttendeeStatus::Attending : EventAttendeeStatus::NotAttending; + + $submission->save(); + + $authentication->author->update(['status' => $request->get('attending') === 'yes' ? EventAttendeeStatus::Attending : EventAttendeeStatus::NotAttending]); + + $data = $validator->validated(); + + if ($data['attending'] === 'yes') { + unset($data['recaptcha-token'], $data['attending']); + + if ($form->is_wizard) { + foreach ($form->steps as $step) { + foreach ($data[$step->label] as $fieldId => $response) { + $submission->fields()->attach( + $fieldId, + ['id' => Str::orderedUuid(), 'response' => $response], + ); + } + } + } else { + foreach ($data as $fieldId => $response) { + $submission->fields()->attach( + $fieldId, + ['id' => Str::orderedUuid(), 'response' => $response], + ); + } + } + + $submission->save(); + } + + DB::commit(); + } catch (Exception $e) { + // TODO: Tag and report this exception. Send the tag to the frontend as a reference. + + DB::rollBack(); + + throw $e; + } + + return response()->json( + [ + 'message' => 'Event registration submitted successfully.', + ] + ); + } +} diff --git a/app-modules/meeting-center/src/Http/Middleware/EnsureEventRegistrationFormIsEmbeddableAndAuthorized.php b/app-modules/meeting-center/src/Http/Middleware/EnsureEventRegistrationFormIsEmbeddableAndAuthorized.php new file mode 100644 index 0000000000..5d041e18ae --- /dev/null +++ b/app-modules/meeting-center/src/Http/Middleware/EnsureEventRegistrationFormIsEmbeddableAndAuthorized.php @@ -0,0 +1,75 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\MeetingCenter\Http\Middleware; + +use Closure; +use Illuminate\Http\Request; +use AdvisingApp\MeetingCenter\Models\Event; +use Symfony\Component\HttpFoundation\Response; + +class EnsureEventRegistrationFormIsEmbeddableAndAuthorized +{ + public function handle(Request $request, Closure $next, string $binding): Response + { + /** @var Event $event */ + $event = $request->route($binding); + + $submissible = $event->eventRegistrationForm; + + $referer = $request->headers->get('referer'); + + if (! $referer) { + return response()->json(['error' => 'Missing referer header.'], 400); + } + + $referer = parse_url($referer)['host']; + + if ($referer != parse_url(config('app.url'))['host']) { + if (! $submissible->embed_enabled) { + return response()->json(['error' => 'Embedding is not enabled for this form.'], 403); + } + + $allowedDomains = collect($submissible->allowed_domains ?? []); + + if (! $allowedDomains->contains($referer)) { + return response()->json(['error' => 'Referer not allowed. Domain must be added to allowed domains list'], 403); + } + } + + return $next($request); + } +} diff --git a/app-modules/meeting-center/src/Livewire/EventAttendeeSubmissionsManager.php b/app-modules/meeting-center/src/Livewire/EventAttendeeSubmissionsManager.php new file mode 100644 index 0000000000..a93aecee71 --- /dev/null +++ b/app-modules/meeting-center/src/Livewire/EventAttendeeSubmissionsManager.php @@ -0,0 +1,97 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\MeetingCenter\Livewire; + +use Livewire\Component; +use Filament\Tables\Table; +use Filament\Forms\Contracts\HasForms; +use Filament\Tables\Actions\ViewAction; +use Filament\Tables\Columns\TextColumn; +use Filament\Tables\Contracts\HasTable; +use Filament\Infolists\Components\Section; +use Filament\Infolists\Components\TextEntry; +use Filament\Forms\Concerns\InteractsWithForms; +use Filament\Tables\Concerns\InteractsWithTable; +use AdvisingApp\MeetingCenter\Models\EventAttendee; +use Illuminate\Database\Eloquent\Relations\HasMany; +use AdvisingApp\MeetingCenter\Models\EventRegistrationFormSubmission; + +class EventAttendeeSubmissionsManager extends Component implements HasForms, HasTable +{ + use InteractsWithForms; + use InteractsWithTable; + + public EventAttendee $record; + + public function render() + { + return view('meeting-center::livewire.event-attendee-submissions-manager'); + } + + public function table(Table $table): Table + { + return $table + ->relationship(fn (): HasMany => $this->record->submissions()) + ->inverseRelationship('author') + ->columns([ + TextColumn::make('submitted_at') + ->label('Submitted At') + ->dateTime() + ->sortable(), + TextColumn::make('attendee_status') + ->label('Submission Status') + ->badge(), + ]) + ->defaultSort('submitted_at', 'desc') + ->actions([ + ViewAction::make() + ->modalHeading(fn (EventRegistrationFormSubmission $record) => 'Submission Details: ' . $record->submitted_at->format('M j, Y H:i:s')) + ->infolist(fn (EventRegistrationFormSubmission $record): array => [ + Section::make('Metadata') + ->schema([ + TextEntry::make('author.email') + ->label('Author Email Address'), + TextEntry::make('attendee_status') + ->label('Submission Status') + ->badge(), + ]) + ->columns(), + ]) + ->modalContent(fn (EventRegistrationFormSubmission $record) => view('meeting-center::event-registration-submission', ['submission' => $record])), + ]); + } +} diff --git a/app-modules/meeting-center/src/Livewire/RenderEventRegistrationForm.php b/app-modules/meeting-center/src/Livewire/RenderEventRegistrationForm.php new file mode 100644 index 0000000000..5a77647953 --- /dev/null +++ b/app-modules/meeting-center/src/Livewire/RenderEventRegistrationForm.php @@ -0,0 +1,60 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\MeetingCenter\Livewire; + +use Livewire\Component; +use Illuminate\Contracts\View\View; +use Filament\Forms\Contracts\HasForms; +use AdvisingApp\MeetingCenter\Models\Event; +use Filament\Forms\Concerns\InteractsWithForms; + +class RenderEventRegistrationForm extends Component implements HasForms +{ + use InteractsWithForms; + + public bool $show = true; + + public Event $event; + + public ?array $data = []; + + public function render(): View + { + return view('meeting-center::livewire.render-event-registration-form') + ->title("{$this->event->title} Registration"); + } +} diff --git a/app-modules/meeting-center/src/Models/Event.php b/app-modules/meeting-center/src/Models/Event.php index 401917e9be..4dba05b52f 100644 --- a/app-modules/meeting-center/src/Models/Event.php +++ b/app-modules/meeting-center/src/Models/Event.php @@ -37,7 +37,12 @@ namespace AdvisingApp\MeetingCenter\Models; use App\Models\BaseModel; +use Illuminate\Database\Eloquent\Relations\HasOne; +use Illuminate\Database\Eloquent\Relations\HasMany; +/** + * @mixin IdeHelperEvent + */ class Event extends BaseModel { protected $fillable = [ @@ -53,4 +58,14 @@ class Event extends BaseModel 'starts_at' => 'datetime', 'ends_at' => 'datetime', ]; + + public function eventRegistrationForm(): HasOne + { + return $this->hasOne(EventRegistrationForm::class, 'event_id'); + } + + public function attendees(): HasMany + { + return $this->hasMany(EventAttendee::class, 'event_id'); + } } diff --git a/app-modules/meeting-center/src/Models/EventAttendee.php b/app-modules/meeting-center/src/Models/EventAttendee.php new file mode 100644 index 0000000000..9590bae852 --- /dev/null +++ b/app-modules/meeting-center/src/Models/EventAttendee.php @@ -0,0 +1,93 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\MeetingCenter\Models; + +use App\Models\BaseModel; +use App\Models\Attributes\NoPermissions; +use Illuminate\Notifications\Notifiable; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; +use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use AdvisingApp\MeetingCenter\Enums\EventAttendeeStatus; + +#[NoPermissions] +/** + * @mixin IdeHelperEventAttendee + */ +class EventAttendee extends BaseModel +{ + use Notifiable; + + protected $fillable = [ + 'status', + 'email', + 'event_id', + ]; + + protected $casts = [ + 'status' => EventAttendeeStatus::class, + ]; + + public function event(): BelongsTo + { + return $this->belongsTo(Event::class, 'event_id'); + } + + public function submissions(): HasMany + { + return $this->hasMany(EventRegistrationFormSubmission::class, 'event_attendee_id'); + } + + public function prospects(): HasMany + { + return $this->hasMany( + related: Prospect::class, + foreignKey: 'email', + localKey: 'email', + ); + } + + public function students(): HasMany + { + return $this->hasMany( + related: Student::class, + foreignKey: 'email', + localKey: 'email', + ); + } +} diff --git a/app-modules/meeting-center/src/Models/EventRegistrationForm.php b/app-modules/meeting-center/src/Models/EventRegistrationForm.php new file mode 100644 index 0000000000..66dda93cad --- /dev/null +++ b/app-modules/meeting-center/src/Models/EventRegistrationForm.php @@ -0,0 +1,92 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\MeetingCenter\Models; + +use AdvisingApp\Form\Enums\Rounding; +use AdvisingApp\Form\Models\Submissible; +use Illuminate\Database\Eloquent\SoftDeletes; +use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\Relations\BelongsTo; + +/** + * @mixin IdeHelperEventRegistrationForm + */ +class EventRegistrationForm extends Submissible +{ + use SoftDeletes; + + protected $fillable = [ + 'form_id', + 'embed_enabled', + 'allowed_domains', + 'is_wizard', + 'recaptcha_enabled', + 'primary_color', + 'rounding', + 'content', + ]; + + protected $casts = [ + 'content' => 'array', + 'embed_enabled' => 'boolean', + 'allowed_domains' => 'array', + 'is_wizard' => 'boolean', + 'recaptcha_enabled' => 'boolean', + 'rounding' => Rounding::class, + ]; + + public function event(): BelongsTo + { + return $this + ->belongsTo(Event::class, 'event_id'); + } + + public function fields(): HasMany + { + return $this->hasMany(EventRegistrationFormField::class, 'form_id'); + } + + public function steps(): HasMany + { + return $this->hasMany(EventRegistrationFormStep::class, 'form_id'); + } + + public function submissions(): HasMany + { + return $this->hasMany(EventRegistrationFormSubmission::class, 'form_id'); + } +} diff --git a/app-modules/meeting-center/src/Models/EventRegistrationFormAuthentication.php b/app-modules/meeting-center/src/Models/EventRegistrationFormAuthentication.php new file mode 100644 index 0000000000..d312ed5e03 --- /dev/null +++ b/app-modules/meeting-center/src/Models/EventRegistrationFormAuthentication.php @@ -0,0 +1,61 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\MeetingCenter\Models; + +use App\Models\Attributes\NoPermissions; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use AdvisingApp\Form\Models\SubmissibleAuthentication; + +#[NoPermissions] +/** + * @property-read EventRegistrationForm $submissible + * + * @mixin IdeHelperEventRegistrationFormAuthentication + */ +class EventRegistrationFormAuthentication extends SubmissibleAuthentication +{ + public function submissible(): BelongsTo + { + return $this + ->belongsTo(EventRegistrationForm::class, 'form_id'); + } + + public function author(): BelongsTo + { + return $this->belongsTo(EventAttendee::class, 'event_attendee_id'); + } +} diff --git a/app-modules/meeting-center/src/Models/EventRegistrationFormField.php b/app-modules/meeting-center/src/Models/EventRegistrationFormField.php new file mode 100644 index 0000000000..7d1867c5c6 --- /dev/null +++ b/app-modules/meeting-center/src/Models/EventRegistrationFormField.php @@ -0,0 +1,71 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\MeetingCenter\Models; + +use AdvisingApp\Form\Models\SubmissibleField; +use Illuminate\Database\Eloquent\Relations\BelongsTo; + +/** + * @mixin IdeHelperEventRegistrationFormField + */ +class EventRegistrationFormField extends SubmissibleField +{ + protected $fillable = [ + 'config', + 'label', + 'type', + 'is_required', + 'form_id', + ]; + + protected $casts = [ + 'config' => 'array', + 'is_required' => 'bool', + ]; + + public function submissible(): BelongsTo + { + return $this + ->belongsTo(EventRegistrationForm::class, 'form_id'); + } + + public function step(): BelongsTo + { + return $this + ->belongsTo(EventRegistrationFormStep::class, 'step_id'); + } +} diff --git a/app-modules/meeting-center/src/Models/EventRegistrationFormStep.php b/app-modules/meeting-center/src/Models/EventRegistrationFormStep.php new file mode 100644 index 0000000000..89ed913a0f --- /dev/null +++ b/app-modules/meeting-center/src/Models/EventRegistrationFormStep.php @@ -0,0 +1,71 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\MeetingCenter\Models; + +use App\Models\Attributes\NoPermissions; +use AdvisingApp\Form\Models\SubmissibleStep; +use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\Relations\BelongsTo; + +#[NoPermissions] +/** + * @mixin IdeHelperEventRegistrationFormStep + */ +class EventRegistrationFormStep extends SubmissibleStep +{ + protected $fillable = [ + 'label', + 'content', + 'sort', + ]; + + protected $casts = [ + 'content' => 'array', + 'sort' => 'integer', + ]; + + public function submissible(): BelongsTo + { + return $this + ->belongsTo(EventRegistrationForm::class, 'form_id'); + } + + public function fields(): HasMany + { + return $this->hasMany(EventRegistrationFormField::class, 'step_id'); + } +} diff --git a/app-modules/meeting-center/src/Models/EventRegistrationFormSubmission.php b/app-modules/meeting-center/src/Models/EventRegistrationFormSubmission.php new file mode 100644 index 0000000000..75d629a0e1 --- /dev/null +++ b/app-modules/meeting-center/src/Models/EventRegistrationFormSubmission.php @@ -0,0 +1,93 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\MeetingCenter\Models; + +use App\Models\User; +use AdvisingApp\Form\Models\Submission; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use AdvisingApp\MeetingCenter\Enums\EventAttendeeStatus; +use Illuminate\Database\Eloquent\Relations\BelongsToMany; +use AdvisingApp\Form\Enums\FormSubmissionRequestDeliveryMethod; + +/** + * @mixin IdeHelperEventRegistrationFormSubmission + */ +class EventRegistrationFormSubmission extends Submission +{ + protected $fillable = [ + 'canceled_at', + 'form_id', + 'attendee_status', + 'request_method', + 'request_note', + 'submitted_at', + ]; + + protected $casts = [ + 'submitted_at' => 'immutable_datetime', + 'canceled_at' => 'immutable_datetime', + 'request_method' => FormSubmissionRequestDeliveryMethod::class, + 'attendee_status' => EventAttendeeStatus::class, + ]; + + public function submissible(): BelongsTo + { + return $this + ->belongsTo(EventRegistrationForm::class, 'form_id'); + } + + public function requester(): BelongsTo + { + return $this->belongsTo(User::class, 'requester_id'); + } + + public function fields(): BelongsToMany + { + return $this->belongsToMany( + EventRegistrationFormField::class, + 'event_registration_form_field_submission', + 'submission_id', + 'field_id', + ) + ->withPivot(['id', 'response']); + } + + public function author(): BelongsTo + { + return $this->belongsTo(EventAttendee::class, 'event_attendee_id'); + } +} diff --git a/app-modules/meeting-center/src/Notifications/AuthenticateEventRegistrationFormNotification.php b/app-modules/meeting-center/src/Notifications/AuthenticateEventRegistrationFormNotification.php new file mode 100644 index 0000000000..09efa9ae1b --- /dev/null +++ b/app-modules/meeting-center/src/Notifications/AuthenticateEventRegistrationFormNotification.php @@ -0,0 +1,70 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\MeetingCenter\Notifications; + +use Illuminate\Bus\Queueable; +use Illuminate\Notifications\Notification; +use Illuminate\Notifications\AnonymousNotifiable; +use AdvisingApp\Notification\Notifications\Messages\MailMessage; +use AdvisingApp\MeetingCenter\Models\EventRegistrationFormAuthentication; + +class AuthenticateEventRegistrationFormNotification extends Notification +{ + use Queueable; + + public function __construct( + public EventRegistrationFormAuthentication $authentication, + public int $code, + ) {} + + /** + * @return array + */ + public function via(object $notifiable): array + { + return ['mail']; + } + + public function toMail(AnonymousNotifiable $notifiable): MailMessage + { + return MailMessage::make() + ->subject("Your authentication code for {$this->authentication->submissible->event->title} registration") + ->line("Your code is: {$this->code}.") + ->line('You should type this code into the form to authenticate yourself.') + ->line('For security reasons, the code will expire in 24 hours, but you can always request another.'); + } +} diff --git a/app-modules/meeting-center/src/Providers/MeetingCenterServiceProvider.php b/app-modules/meeting-center/src/Providers/MeetingCenterServiceProvider.php index 4da3cd67f1..e3dc80d32a 100644 --- a/app-modules/meeting-center/src/Providers/MeetingCenterServiceProvider.php +++ b/app-modules/meeting-center/src/Providers/MeetingCenterServiceProvider.php @@ -37,6 +37,7 @@ namespace AdvisingApp\MeetingCenter\Providers; use Filament\Panel; +use Livewire\Livewire; use Illuminate\Support\ServiceProvider; use AdvisingApp\MeetingCenter\Models\Event; use Illuminate\Console\Scheduling\Schedule; @@ -44,10 +45,17 @@ use AdvisingApp\MeetingCenter\Jobs\SyncCalendars; use AdvisingApp\MeetingCenter\MeetingCenterPlugin; use AdvisingApp\MeetingCenter\Models\CalendarEvent; +use AdvisingApp\MeetingCenter\Models\EventAttendee; use Illuminate\Database\Eloquent\Relations\Relation; use AdvisingApp\Authorization\AuthorizationRoleRegistry; +use AdvisingApp\MeetingCenter\Models\EventRegistrationForm; use AdvisingApp\Authorization\AuthorizationPermissionRegistry; use AdvisingApp\MeetingCenter\Observers\CalendarEventObserver; +use AdvisingApp\MeetingCenter\Models\EventRegistrationFormStep; +use AdvisingApp\MeetingCenter\Models\EventRegistrationFormField; +use AdvisingApp\MeetingCenter\Models\EventRegistrationFormSubmission; +use AdvisingApp\MeetingCenter\Livewire\EventAttendeeSubmissionsManager; +use AdvisingApp\MeetingCenter\Models\EventRegistrationFormAuthentication; class MeetingCenterServiceProvider extends ServiceProvider { @@ -62,6 +70,12 @@ public function boot(): void 'calendar' => Calendar::class, 'calendar_event' => CalendarEvent::class, 'event' => Event::class, + 'event_attendee' => EventAttendee::class, + 'event_registration_form' => EventRegistrationForm::class, + 'event_registration_form_authentication' => EventRegistrationFormAuthentication::class, + 'event_registration_form_field' => EventRegistrationFormField::class, + 'event_registration_form_step' => EventRegistrationFormStep::class, + 'event_registration_form_submission' => EventRegistrationFormSubmission::class, ]); $this->callAfterResolving(Schedule::class, function (Schedule $schedule) { @@ -74,6 +88,8 @@ public function boot(): void $this->registerRolesAndPermissions(); $this->registerObservers(); + + Livewire::component('event-attendee-submissions-manager', EventAttendeeSubmissionsManager::class); } protected function registerRolesAndPermissions(): void diff --git a/app-modules/portal/src/Filament/Pages/ManagePortalSettings.php b/app-modules/portal/src/Filament/Pages/ManagePortalSettings.php index 3b49e86f09..ae234b0eab 100644 --- a/app-modules/portal/src/Filament/Pages/ManagePortalSettings.php +++ b/app-modules/portal/src/Filament/Pages/ManagePortalSettings.php @@ -135,12 +135,12 @@ public function form(Form $form): Form ->label('Files and Documents'), Toggle::make('has_forms') ->label('Forms') - ->disabled(! Gate::check(Feature::DynamicForms->getGateName())) + ->disabled(! Gate::check(Feature::OnlineForms->getGateName())) ->hintIcon(fn (Toggle $component) => $component->isDisabled() ? 'heroicon-m-lock-closed' : null) ->hintIconTooltip('Forms are not a part of your current subscription.'), Toggle::make('has_surveys') ->label('Surveys') - ->disabled(! Gate::check(Feature::ConductSurveys->getGateName())) + ->disabled(! Gate::check(Feature::OnlineSurveys->getGateName())) ->hintIcon(fn (Toggle $component) => $component->isDisabled() ? 'heroicon-m-lock-closed' : null) ->hintIconTooltip('Surveys are not a part of your current subscription.'), ]) diff --git a/app-modules/prospect/src/Filament/Resources/ProspectResource/Pages/ListProspects.php b/app-modules/prospect/src/Filament/Resources/ProspectResource/Pages/ListProspects.php index cc455741c8..a5cc897835 100644 --- a/app-modules/prospect/src/Filament/Resources/ProspectResource/Pages/ListProspects.php +++ b/app-modules/prospect/src/Filament/Resources/ProspectResource/Pages/ListProspects.php @@ -56,7 +56,6 @@ use Filament\Resources\Pages\ListRecords; use Filament\Tables\Filters\SelectFilter; use Illuminate\Database\Eloquent\Builder; -use App\Concerns\FilterTableWithOpenSearch; use Filament\Tables\Actions\BulkActionGroup; use Illuminate\Database\Eloquent\Collection; use Filament\Tables\Actions\DeleteBulkAction; @@ -71,14 +70,11 @@ use AdvisingApp\CareTeam\Filament\Actions\ToggleCareTeamBulkAction; use AdvisingApp\Notification\Filament\Actions\SubscribeTableAction; use AdvisingApp\CaseloadManagement\Actions\TranslateCaseloadFilters; -use App\Filament\Columns\OpenSearch\TextColumn as OpenSearchTextColumn; -use App\Filament\Filters\OpenSearch\SelectFilter as OpenSearchSelectFilter; use AdvisingApp\Engagement\Filament\Actions\Contracts\HasBulkEngagementAction; use AdvisingApp\Engagement\Filament\Actions\Concerns\ImplementsHasBulkEngagementAction; class ListProspects extends ListRecords implements HasBulkEngagementAction { - use FilterTableWithOpenSearch; use ImplementsHasBulkEngagementAction; protected static string $resource = ProspectResource::class; @@ -88,16 +84,16 @@ public function table(Table $table): Table return $table ->columns([ IdColumn::make(), - OpenSearchTextColumn::make(Prospect::displayNameKey()) + TextColumn::make(Prospect::displayNameKey()) ->label('Name') ->searchable() ->sortable(), - OpenSearchTextColumn::make('email') + TextColumn::make('email') ->label('Email') ->translateLabel() ->searchable() ->sortable(), - OpenSearchTextColumn::make('mobile') + TextColumn::make('mobile') ->label('Mobile') ->translateLabel() ->searchable() @@ -147,11 +143,11 @@ public function table(Table $table): Table ->searchable() ->optionsLimit(20) ->query(fn (Builder $query, array $data) => $this->caseloadFilter($query, $data)), - OpenSearchSelectFilter::make('status_id') + SelectFilter::make('status_id') ->relationship('status', 'name') ->multiple() ->preload(), - OpenSearchSelectFilter::make('source_id') + SelectFilter::make('source_id') ->relationship('source', 'name') ->multiple() ->preload(), diff --git a/app-modules/prospect/src/Models/Prospect.php b/app-modules/prospect/src/Models/Prospect.php index 00baff3249..d0aa1a0f80 100644 --- a/app-modules/prospect/src/Models/Prospect.php +++ b/app-modules/prospect/src/Models/Prospect.php @@ -45,7 +45,6 @@ use Illuminate\Notifications\Notifiable; use OwenIt\Auditing\Contracts\Auditable; use AdvisingApp\CareTeam\Models\CareTeam; -use OpenSearch\ScoutDriverPlus\Searchable; use AdvisingApp\Form\Models\FormSubmission; use Illuminate\Database\Eloquent\SoftDeletes; use AdvisingApp\Engagement\Models\EngagementFile; @@ -84,7 +83,6 @@ class Prospect extends BaseModel implements Auditable, Subscribable, Educatable, use HasManyMorphedEngagementResponses; use HasManyMorphedInteractions; use HasSubscriptions; - use Searchable; use NotifiableViaSms; protected $fillable = [ @@ -115,39 +113,6 @@ class Prospect extends BaseModel implements Auditable, Subscribable, Educatable, 'birthdate' => 'date', ]; - public function searchableAs(): string - { - return config('scout.prefix') . 'prospects'; - } - - public function toSearchableArray(): array - { - return [ - 'id' => (int) $this->getScoutKey(), - 'status_id' => $this->status_id, - 'source_id' => $this->source_id, - 'first_name' => $this->first_name, - 'last_name' => $this->last_name, - 'full_name' => $this->full_name, - 'preferred' => $this->preferred, - 'description' => $this->description, - 'email' => $this->email, - 'email_2' => $this->email_2, - 'mobile' => $this->mobile, - 'sms_opt_out' => $this->sms_opt_out, - 'email_bounce' => $this->email_bounce, - 'phone' => $this->phone, - 'address' => $this->address, - 'address_2' => $this->address_2, - 'birthdate' => $this->birthdate, - 'hsgrad' => (int) $this->hsgrad, - 'assigned_to_id' => $this->assigned_to_id, - 'created_by_id' => $this->created_by_id, - 'created_at' => $this->created_at->format('Y-m-d H:i:s'), - 'updated_at' => $this->updated_at->format('Y-m-d H:i:s'), - ]; - } - public function identifier(): string { return $this->id; diff --git a/app-modules/service-management/src/Models/ServiceRequestStatus.php b/app-modules/service-management/src/Models/ServiceRequestStatus.php index 22c8749bc9..5250ece7c4 100644 --- a/app-modules/service-management/src/Models/ServiceRequestStatus.php +++ b/app-modules/service-management/src/Models/ServiceRequestStatus.php @@ -40,7 +40,6 @@ use App\Models\BaseModel; use OwenIt\Auditing\Contracts\Auditable; use Illuminate\Database\Eloquent\SoftDeletes; -use Illuminate\Database\Eloquent\Concerns\HasUuids; use Illuminate\Database\Eloquent\Relations\HasMany; use AdvisingApp\ServiceManagement\Enums\ColumnColorOptions; use AdvisingApp\Audit\Models\Concerns\Auditable as AuditableTrait; @@ -52,7 +51,6 @@ class ServiceRequestStatus extends BaseModel implements Auditable { use SoftDeletes; - use HasUuids; use AuditableTrait; protected $fillable = [ diff --git a/app-modules/survey/config/roles/web/survey_roles.php b/app-modules/survey/config/roles/web/survey_management.php similarity index 100% rename from app-modules/survey/config/roles/web/survey_roles.php rename to app-modules/survey/config/roles/web/survey_management.php diff --git a/app-modules/survey/src/Filament/Blocks/CheckboxSurveyFieldBlock.php b/app-modules/survey/src/Filament/Blocks/CheckboxSurveyFieldBlock.php new file mode 100644 index 0000000000..6b5e23ae58 --- /dev/null +++ b/app-modules/survey/src/Filament/Blocks/CheckboxSurveyFieldBlock.php @@ -0,0 +1,47 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\Survey\Filament\Blocks; + +use AdvisingApp\Form\Filament\Blocks\CheckboxFormFieldBlock; + +class CheckboxSurveyFieldBlock extends CheckboxFormFieldBlock +{ + public function getLabel(): string + { + return 'Multiple Choice'; + } +} diff --git a/app-modules/survey/src/Filament/Blocks/RadioSurveyFieldBlock.php b/app-modules/survey/src/Filament/Blocks/RadioSurveyFieldBlock.php new file mode 100644 index 0000000000..3b92ba8995 --- /dev/null +++ b/app-modules/survey/src/Filament/Blocks/RadioSurveyFieldBlock.php @@ -0,0 +1,47 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\Survey\Filament\Blocks; + +use AdvisingApp\Form\Filament\Blocks\RadioFormFieldBlock; + +class RadioSurveyFieldBlock extends RadioFormFieldBlock +{ + public function getLabel(): string + { + return 'Choice (Radio)'; + } +} diff --git a/app-modules/survey/src/Filament/Blocks/SelectSurveyFieldBlock.php b/app-modules/survey/src/Filament/Blocks/SelectSurveyFieldBlock.php new file mode 100644 index 0000000000..b700e2eb82 --- /dev/null +++ b/app-modules/survey/src/Filament/Blocks/SelectSurveyFieldBlock.php @@ -0,0 +1,47 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\Survey\Filament\Blocks; + +use AdvisingApp\Form\Filament\Blocks\SelectFormFieldBlock; + +class SelectSurveyFieldBlock extends SelectFormFieldBlock +{ + public function getLabel(): string + { + return 'Choice (Dropdown)'; + } +} diff --git a/app-modules/survey/src/Filament/Blocks/SurveyFieldBlockRegistry.php b/app-modules/survey/src/Filament/Blocks/SurveyFieldBlockRegistry.php new file mode 100644 index 0000000000..2b37c5e8ff --- /dev/null +++ b/app-modules/survey/src/Filament/Blocks/SurveyFieldBlockRegistry.php @@ -0,0 +1,72 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\Survey\Filament\Blocks; + +use AdvisingApp\Form\Filament\Blocks\EmailFormFieldBlock; +use AdvisingApp\Form\Filament\Blocks\NumberFormFieldBlock; +use AdvisingApp\Form\Filament\Blocks\EducatableEmailFormFieldBlock; + +class SurveyFieldBlockRegistry +{ + /** + * @return array> + */ + public static function get(): array + { + return [ + EducatableEmailFormFieldBlock::class, + TextInputSurveyFieldBlock::class, + TextAreaSurveyFieldBlock::class, + SelectSurveyFieldBlock::class, + RadioSurveyFieldBlock::class, + CheckboxSurveyFieldBlock::class, + EmailFormFieldBlock::class, + NumberFormFieldBlock::class, + ]; + } + + /** + * @return array> + */ + public static function keyByType(): array + { + /** @var FormFieldBlock $block */ + return collect(static::get()) + ->mapWithKeys(fn (string $block): array => [$block::type() => $block]) + ->all(); + } +} diff --git a/app-modules/survey/src/Filament/Blocks/TextAreaSurveyFieldBlock.php b/app-modules/survey/src/Filament/Blocks/TextAreaSurveyFieldBlock.php new file mode 100644 index 0000000000..b713bd9a90 --- /dev/null +++ b/app-modules/survey/src/Filament/Blocks/TextAreaSurveyFieldBlock.php @@ -0,0 +1,47 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\Survey\Filament\Blocks; + +use AdvisingApp\Form\Filament\Blocks\TextAreaFormFieldBlock; + +class TextAreaSurveyFieldBlock extends TextAreaFormFieldBlock +{ + public function getLabel(): string + { + return 'Question (Multi-Line)'; + } +} diff --git a/app-modules/survey/src/Filament/Blocks/TextInputSurveyFieldBlock.php b/app-modules/survey/src/Filament/Blocks/TextInputSurveyFieldBlock.php new file mode 100644 index 0000000000..d414fb092e --- /dev/null +++ b/app-modules/survey/src/Filament/Blocks/TextInputSurveyFieldBlock.php @@ -0,0 +1,47 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\Survey\Filament\Blocks; + +use AdvisingApp\Form\Filament\Blocks\TextInputFormFieldBlock; + +class TextInputSurveyFieldBlock extends TextInputFormFieldBlock +{ + public function getLabel(): string + { + return 'Question (Single Line)'; + } +} diff --git a/app-modules/survey/src/Filament/Resources/SurveyResource/Pages/Concerns/HasSharedFormConfiguration.php b/app-modules/survey/src/Filament/Resources/SurveyResource/Pages/Concerns/HasSharedFormConfiguration.php index 8999527271..332948559d 100644 --- a/app-modules/survey/src/Filament/Resources/SurveyResource/Pages/Concerns/HasSharedFormConfiguration.php +++ b/app-modules/survey/src/Filament/Resources/SurveyResource/Pages/Concerns/HasSharedFormConfiguration.php @@ -53,8 +53,8 @@ use AdvisingApp\Survey\Models\SurveyStep; use AdvisingApp\Survey\Models\SurveyField; use FilamentTiptapEditor\Enums\TiptapOutput; -use AdvisingApp\Form\Filament\Blocks\FormFieldBlockRegistry; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; +use AdvisingApp\Survey\Filament\Blocks\SurveyFieldBlockRegistry; use AdvisingApp\IntegrationGoogleRecaptcha\Settings\GoogleRecaptchaSettings; trait HasSharedFormConfiguration @@ -146,7 +146,7 @@ public function fieldBuilder(): TiptapEditor { return TiptapEditor::make('content') ->output(TiptapOutput::Json) - ->blocks(FormFieldBlockRegistry::get()) + ->blocks(SurveyFieldBlockRegistry::get()) ->tools(['bold', 'italic', 'small', '|', 'heading', 'bullet-list', 'ordered-list', 'hr', '|', 'link', 'grid', 'blocks']) ->placeholder('Drag blocks here to build your survey') ->hiddenLabel() diff --git a/app-modules/survey/src/Http/Controllers/SurveyWidgetController.php b/app-modules/survey/src/Http/Controllers/SurveyWidgetController.php index 5c8a72a9ef..8a1c815907 100644 --- a/app-modules/survey/src/Http/Controllers/SurveyWidgetController.php +++ b/app-modules/survey/src/Http/Controllers/SurveyWidgetController.php @@ -53,7 +53,6 @@ use AdvisingApp\Form\Actions\GenerateFormKitSchema; use AdvisingApp\Survey\Models\SurveyAuthentication; use AdvisingApp\Form\Actions\GenerateSubmissibleValidation; -use AdvisingApp\Application\Models\ApplicationAuthentication; use AdvisingApp\Form\Actions\ResolveSubmissionAuthorFromEmail; use AdvisingApp\Form\Notifications\AuthenticateFormNotification; use AdvisingApp\Form\Filament\Blocks\EducatableEmailFormFieldBlock; @@ -119,7 +118,7 @@ public function requestAuthentication(Request $request, ResolveSubmissionAuthorF ]); } - public function authenticate(Request $request, Survey $survey, ApplicationAuthentication $authentication): JsonResponse + public function authenticate(Request $request, Survey $survey, SurveyAuthentication $authentication): JsonResponse { if ($authentication->isExpired()) { return response()->json([ @@ -139,8 +138,8 @@ public function authenticate(Request $request, Survey $survey, ApplicationAuthen return response()->json([ 'submission_url' => URL::signedRoute('surveys.submit', [ - 'survey' => $authentication, - 'application' => $authentication->submissible, + 'authentication' => $authentication, + 'survey' => $authentication->submissible, ]), ]); } @@ -154,7 +153,7 @@ public function store( $authentication = $request->query('authentication'); if (filled($authentication)) { - $authentication = ApplicationAuthentication::findOrFail($authentication); + $authentication = SurveyAuthentication::findOrFail($authentication); } if ( diff --git a/app-modules/survey/src/Http/Middleware/EnsureSurveysFeatureIsActive.php b/app-modules/survey/src/Http/Middleware/EnsureSurveysFeatureIsActive.php index 2c0d37c894..9c211af70a 100644 --- a/app-modules/survey/src/Http/Middleware/EnsureSurveysFeatureIsActive.php +++ b/app-modules/survey/src/Http/Middleware/EnsureSurveysFeatureIsActive.php @@ -45,7 +45,7 @@ class EnsureSurveysFeatureIsActive { public function handle(Request $request, Closure $next): Response { - if (! app(LicenseSettings::class)->data->addons->conductSurveys) { + if (! app(LicenseSettings::class)->data->addons->onlineSurveys) { return response()->json(['error' => 'Surveys is not enabled.'], 403); } diff --git a/app/DataTransferObjects/LicenseManagement/LicenseAddonsData.php b/app/DataTransferObjects/LicenseManagement/LicenseAddonsData.php index 4f131c4bdf..add8d67d58 100644 --- a/app/DataTransferObjects/LicenseManagement/LicenseAddonsData.php +++ b/app/DataTransferObjects/LicenseManagement/LicenseAddonsData.php @@ -44,13 +44,13 @@ class LicenseAddonsData extends Data { public function __construct( + public bool $onlineForms, + public bool $onlineSurveys, public bool $onlineAdmissions, - public bool $realtimeChat, - public bool $dynamicForms, - public bool $conductSurveys, - public bool $personalAssistant, public bool $serviceManagement, public bool $knowledgeManagement, - public bool $studentAndProspectPortal, + public bool $eventManagement, + public bool $realtimeChat, + public bool $mobileApps, ) {} } diff --git a/app/DataTransferObjects/LicenseManagement/LicenseLimitsData.php b/app/DataTransferObjects/LicenseManagement/LicenseLimitsData.php index 21d04a3972..884e07af48 100644 --- a/app/DataTransferObjects/LicenseManagement/LicenseLimitsData.php +++ b/app/DataTransferObjects/LicenseManagement/LicenseLimitsData.php @@ -44,8 +44,9 @@ class LicenseLimitsData extends Data { public function __construct( - public int $crmSeats, - public int $analyticsSeats, + public int $conversationalAiSeats, + public int $retentionCrmSeats, + public int $recruitmentCrmSeats, public int $emails, public int $sms, public string $resetDate, diff --git a/app/Enums/Feature.php b/app/Enums/Feature.php index 188146291c..a7e8914c0a 100644 --- a/app/Enums/Feature.php +++ b/app/Enums/Feature.php @@ -42,21 +42,20 @@ enum Feature: string { - case OnlineAdmissions = 'online-admissions'; - - case RealtimeChat = 'realtime-chat'; - - case DynamicForms = 'dynamic-forms'; + case OnlineForms = 'online-forms'; - case ConductSurveys = 'conduct-surveys'; + case OnlineSurveys = 'online-surveys'; - case PersonalAssistant = 'personal-assistant'; + case OnlineAdmissions = 'online-admissions'; case ServiceManagement = 'service-management'; case KnowledgeManagement = 'knowledge-management'; - case StudentAndProspectPortal = 'student-and-prospect-portal'; + case EventManagement = 'event-management'; + case RealtimeChat = 'realtime-chat'; + + case MobileApps = 'mobile-apps'; public function generateGate(): void { diff --git a/app/Filament/Pages/ManageLicenseSettings.php b/app/Filament/Pages/ManageLicenseSettings.php index 60c226c862..60ac1625a5 100644 --- a/app/Filament/Pages/ManageLicenseSettings.php +++ b/app/Filament/Pages/ManageLicenseSettings.php @@ -96,12 +96,16 @@ public function form(Form $form): Form ->columns() ->schema( [ - TextInput::make('data.limits.crmSeats') - ->label('CRM Seats') + TextInput::make('data.limits.conversationalAiSeats') + ->label('Artificial Intelligence Seats') ->numeric() ->required(), - TextInput::make('data.limits.analyticsSeats') - ->label('Analytics Seats') + TextInput::make('data.limits.retentionCrmSeats') + ->label('Student Success / Retention Seats') + ->numeric() + ->required(), + TextInput::make('data.limits.recruitmentCrmSeats') + ->label('Recruitment CRM Seats') ->numeric() ->required(), TextInput::make('data.limits.emails') @@ -121,22 +125,22 @@ public function form(Form $form): Form ->columns() ->schema( [ + Toggle::make('data.addons.onlineForms') + ->label('Online Forms'), + Toggle::make('data.addons.onlineSurveys') + ->label('Online Surveys'), Toggle::make('data.addons.onlineAdmissions') ->label('Online Admissions'), - Toggle::make('data.addons.realtimeChat') - ->label('Realtime Chat'), - Toggle::make('data.addons.dynamicForms') - ->label('Dynamic Forms'), - Toggle::make('data.addons.conductSurveys') - ->label('Conduct Surveys'), - Toggle::make('data.addons.personalAssistant') - ->label('Personal Assistant'), Toggle::make('data.addons.serviceManagement') ->label('Service Management'), Toggle::make('data.addons.knowledgeManagement') ->label('Knowledge Management'), - Toggle::make('data.addons.studentAndProspectPortal') - ->label('Student and Prospect Portal'), + Toggle::make('data.addons.eventManagement') + ->label('Event Management'), + Toggle::make('data.addons.realtimeChat') + ->label('Realtime Chat'), + Toggle::make('data.addons.mobileApps') + ->label('Mobile Apps'), ] ), ]); diff --git a/app/Filament/Resources/UserResource.php b/app/Filament/Resources/UserResource.php index 4ef2fd43ee..e799e88286 100644 --- a/app/Filament/Resources/UserResource.php +++ b/app/Filament/Resources/UserResource.php @@ -55,6 +55,7 @@ use App\Filament\Resources\UserResource\Pages\ListUsers; use App\Filament\Resources\UserResource\Pages\CreateUser; use App\Filament\Resources\UserResource\RelationManagers\RolesRelationManager; +use App\Filament\Resources\UserResource\RelationManagers\LicensesRelationManager; use App\Filament\Resources\UserResource\RelationManagers\RoleGroupsRelationManager; use App\Filament\Resources\UserResource\RelationManagers\PermissionsRelationManager; @@ -128,6 +129,7 @@ public static function getRelations(): array RoleGroupsRelationManager::class, RolesRelationManager::class, PermissionsRelationManager::class, + LicensesRelationManager::class, ]; } diff --git a/app/Filament/Resources/UserResource/Pages/ListUsers.php b/app/Filament/Resources/UserResource/Pages/ListUsers.php index 287c793daa..3edd59677c 100644 --- a/app/Filament/Resources/UserResource/Pages/ListUsers.php +++ b/app/Filament/Resources/UserResource/Pages/ListUsers.php @@ -36,10 +36,7 @@ namespace App\Filament\Resources\UserResource\Pages; -use App\Models\User; -use App\Settings\LicenseSettings; use Filament\Actions\CreateAction; -use Illuminate\Support\HtmlString; use App\Filament\Resources\UserResource; use Filament\Resources\Pages\ListRecords; use Illuminate\Contracts\Support\Htmlable; @@ -50,10 +47,14 @@ class ListUsers extends ListRecords public function getSubheading(): string | Htmlable | null { - return new HtmlString(view('crm-seats', [ - 'count' => User::count(), - 'max' => app(LicenseSettings::class)->data->limits->crmSeats, - ])->render()); + // TODO: Either remove or change to show all possible seats + + //return new HtmlString(view('crm-seats', [ + // 'count' => User::count(), + // 'max' => app(LicenseSettings::class)->data->limits->crmSeats, + //])->render()); + + return null; } protected function getHeaderActions(): array diff --git a/app/Filament/Resources/UserResource/RelationManagers/LicensesRelationManager.php b/app/Filament/Resources/UserResource/RelationManagers/LicensesRelationManager.php new file mode 100644 index 0000000000..1487568274 --- /dev/null +++ b/app/Filament/Resources/UserResource/RelationManagers/LicensesRelationManager.php @@ -0,0 +1,104 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace App\Filament\Resources\UserResource\RelationManagers; + +use App\Models\User; +use Filament\Forms\Form; +use Filament\Tables\Table; +use Illuminate\Validation\Rule; +use Filament\Forms\Components\Select; +use Filament\Tables\Columns\TextColumn; +use Filament\Tables\Actions\CreateAction; +use Filament\Tables\Actions\DeleteAction; +use Filament\Tables\Actions\BulkActionGroup; +use Filament\Tables\Actions\DeleteBulkAction; +use AdvisingApp\Authorization\Enums\LicenseType; +use AdvisingApp\Authorization\Rules\LicenseTypeUsageRule; +use App\Filament\Resources\RelationManagers\RelationManager; + +class LicensesRelationManager extends RelationManager +{ + protected static string $relationship = 'licenses'; + + public function form(Form $form): Form + { + return $form + ->schema([ + Select::make('type') + ->options(LicenseType::class) + ->enum(LicenseType::class) + ->rule( + Rule::unique('licenses', 'type') + ->where('user_id', $this->getOwnerRecord()->getKey()) + ->whereNull('deleted_at'), + ) + ->rule(new LicenseTypeUsageRule()) + ->disableOptionWhen(function (string $value) { + /** @var User $ownerRecord */ + $ownerRecord = $this->getOwnerRecord(); + + return ! LicenseType::from($value)->hasAvailableLicenses() || $ownerRecord->licenses()->where('type', $value)->exists(); + }) + ->required(), + ]); + } + + public function table(Table $table): Table + { + return $table + ->recordTitleAttribute('type') + ->columns([ + TextColumn::make('type'), + TextColumn::make('created_at') + ->dateTime(), + ]) + ->headerActions([ + CreateAction::make(), + ]) + ->actions([ + DeleteAction::make(), + ]) + ->bulkActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ]), + ]) + ->emptyStateActions([ + CreateAction::make(), + ]); + } +} diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php index 88dddf1747..660c731b42 100644 --- a/app/Http/Middleware/VerifyCsrfToken.php +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -49,6 +49,7 @@ class VerifyCsrfToken extends Middleware '/api/forms/*', '/api/applications/*', '/api/surveys/*', + '/api/event-registration/*', '/graphql/*', ]; } diff --git a/app/Models/User.php b/app/Models/User.php index 798a326208..08cb1dc89b 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -52,6 +52,7 @@ use Lab404\Impersonate\Models\Impersonate; use Filament\Models\Contracts\FilamentUser; use Spatie\MediaLibrary\InteractsWithMedia; +use AdvisingApp\Authorization\Models\License; use Illuminate\Database\Eloquent\SoftDeletes; use AdvisingApp\MeetingCenter\Models\Calendar; use AdvisingApp\Assistant\Models\AssistantChat; @@ -195,6 +196,11 @@ public function caseloads(): HasMany return $this->hasMany(Caseload::class); } + public function licenses(): HasMany + { + return $this->hasMany(License::class, 'user_id'); + } + public function subscriptions(): HasMany { return $this->hasMany(Subscription::class); diff --git a/app/Policies/UserPolicy.php b/app/Policies/UserPolicy.php index 120acf24fc..93eb31eb33 100644 --- a/app/Policies/UserPolicy.php +++ b/app/Policies/UserPolicy.php @@ -38,9 +38,7 @@ use App\Models\User; use App\Models\Authenticatable; -use App\Settings\LicenseSettings; use Illuminate\Auth\Access\Response; -use App\Support\FeatureAccessResponse; class UserPolicy { @@ -62,10 +60,6 @@ public function view(Authenticatable $authenticatable, User $model): Response public function create(Authenticatable $authenticatable): Response { - if (User::count() >= app(LicenseSettings::class)->data->limits->crmSeats) { - return FeatureAccessResponse::deny('You have reached the maximum number of users allowed by your license.'); - } - return $authenticatable->canOrElse( abilities: 'user.create', denyResponse: 'You do not have permission to create users.' @@ -90,10 +84,6 @@ public function delete(Authenticatable $authenticatable, User $model): Response public function restore(Authenticatable $authenticatable, User $model): Response { - if (User::count() >= app(LicenseSettings::class)->data->limits->crmSeats) { - return FeatureAccessResponse::deny('You have reached the maximum number of users allowed by your license.'); - } - return $authenticatable->canOrElse( abilities: ['user.*.restore', "user.{$model->id}.restore"], denyResponse: 'You do not have permission to restore this user.' diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index f54cc6fd41..4483cd73a2 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -64,6 +64,7 @@ public function boot(): void if (config('app.force_https')) { URL::forceScheme('https'); + $this->app['request']->server->set('HTTPS', true); } } } diff --git a/composer.json b/composer.json index 9ac9e26dce..97e808d8fb 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ "php": "8.2.*", "ext-gd": "*", "ext-pdo": "*", - "awcodes/filament-tiptap-editor": "^3.2.14", + "awcodes/filament-tiptap-editor": "^3.2.17", "aws/aws-php-sns-message-validator": "^1.8.0", "aws/aws-sdk-php": "^3.293", "barryvdh/laravel-debugbar": "^3.9", diff --git a/composer.lock b/composer.lock index 7f43c3aa26..ba8789147b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4135a59df44c5333303e7a1b6f1ff947", + "content-hash": "19b34ef965a1ec4aa7ec0deb038e20bd", "packages": [ { "name": "amphp/amp", @@ -755,16 +755,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.295.3", + "version": "3.295.4", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "3346f60c6c5075453f90f703693f764dad76a3a8" + "reference": "2372661db989fe4229abd95f4434b37252076d58" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/3346f60c6c5075453f90f703693f764dad76a3a8", - "reference": "3346f60c6c5075453f90f703693f764dad76a3a8", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/2372661db989fe4229abd95f4434b37252076d58", + "reference": "2372661db989fe4229abd95f4434b37252076d58", "shasum": "" }, "require": { @@ -844,9 +844,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.295.3" + "source": "https://github.com/aws/aws-sdk-php/tree/3.295.4" }, - "time": "2023-12-28T19:32:33+00:00" + "time": "2023-12-29T19:07:49+00:00" }, { "name": "barryvdh/laravel-debugbar", @@ -10196,16 +10196,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "3.0.34", + "version": "3.0.35", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "56c79f16a6ae17e42089c06a2144467acc35348a" + "reference": "4b1827beabce71953ca479485c0ae9c51287f2fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/56c79f16a6ae17e42089c06a2144467acc35348a", - "reference": "56c79f16a6ae17e42089c06a2144467acc35348a", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/4b1827beabce71953ca479485c0ae9c51287f2fe", + "reference": "4b1827beabce71953ca479485c0ae9c51287f2fe", "shasum": "" }, "require": { @@ -10286,7 +10286,7 @@ ], "support": { "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.34" + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.35" }, "funding": [ { @@ -10302,7 +10302,7 @@ "type": "tidelift" } ], - "time": "2023-11-27T11:13:31+00:00" + "time": "2023-12-29T01:59:53+00:00" }, { "name": "phpstan/phpdoc-parser", @@ -17183,16 +17183,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.43.0", + "version": "v3.44.0", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "39b5632c39ca9deb4eb7e670ba96fcf5c3a72e3c" + "reference": "5445834057a744c1a434ed60fcac566b4de3a0f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/39b5632c39ca9deb4eb7e670ba96fcf5c3a72e3c", - "reference": "39b5632c39ca9deb4eb7e670ba96fcf5c3a72e3c", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/5445834057a744c1a434ed60fcac566b4de3a0f2", + "reference": "5445834057a744c1a434ed60fcac566b4de3a0f2", "shasum": "" }, "require": { @@ -17261,7 +17261,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.43.0" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.44.0" }, "funding": [ { @@ -17269,7 +17269,7 @@ "type": "github" } ], - "time": "2023-12-28T17:36:39+00:00" + "time": "2023-12-29T20:21:16+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -20800,28 +20800,28 @@ }, { "name": "ta-tikoma/phpunit-architecture-test", - "version": "0.7.5", + "version": "0.7.6", "source": { "type": "git", "url": "https://github.com/ta-tikoma/phpunit-architecture-test.git", - "reference": "9eb08437e8f0c0c75cc947a373cf49672c335827" + "reference": "a252cd9488fd62f3c8c6cafa303b1b96e9df24e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ta-tikoma/phpunit-architecture-test/zipball/9eb08437e8f0c0c75cc947a373cf49672c335827", - "reference": "9eb08437e8f0c0c75cc947a373cf49672c335827", + "url": "https://api.github.com/repos/ta-tikoma/phpunit-architecture-test/zipball/a252cd9488fd62f3c8c6cafa303b1b96e9df24e0", + "reference": "a252cd9488fd62f3c8c6cafa303b1b96e9df24e0", "shasum": "" }, "require": { - "nikic/php-parser": "^4.15.4", + "nikic/php-parser": "^4.18.0", "php": "^8.1.0", "phpdocumentor/reflection-docblock": "^5.3.0", - "phpunit/phpunit": "^10.1.1", - "symfony/finder": "^6.2.7 || ^7.0.0" + "phpunit/phpunit": "^10.5.5", + "symfony/finder": "^6.4.0 || ^7.0.0" }, "require-dev": { - "laravel/pint": "^1.9.0", - "phpstan/phpstan": "^1.10.13" + "laravel/pint": "^1.13.7", + "phpstan/phpstan": "^1.10.50" }, "type": "library", "autoload": { @@ -20853,9 +20853,9 @@ ], "support": { "issues": "https://github.com/ta-tikoma/phpunit-architecture-test/issues", - "source": "https://github.com/ta-tikoma/phpunit-architecture-test/tree/0.7.5" + "source": "https://github.com/ta-tikoma/phpunit-architecture-test/tree/0.7.6" }, - "time": "2023-10-12T15:31:50+00:00" + "time": "2023-12-29T13:14:58+00:00" }, { "name": "theseer/tokenizer", diff --git a/database/settings/2023_11_29_192230_create_license_settings.php b/database/settings/2023_11_29_192230_create_license_settings.php index 7f487669cc..3d3af1ade5 100644 --- a/database/settings/2023_11_29_192230_create_license_settings.php +++ b/database/settings/2023_11_29_192230_create_license_settings.php @@ -55,21 +55,22 @@ public function up(): void 'end_date' => now()->addYear(), ], 'limits' => [ - 'crm_seats' => 30, - 'analytics_seats' => 15, + 'conversational_ai_seats' => 50, + 'retention_crm_seats' => 25, + 'recruitment_crm_seats' => 10, 'emails' => 1000, 'sms' => 1000, 'reset_date' => now()->format('m-d'), ], 'addons' => [ + 'online_forms' => true, + 'online_surveys' => true, 'online_admissions' => true, - 'realtime_chat' => true, - 'dynamic_forms' => true, - 'conduct_surveys' => true, - 'personal_assistant' => true, 'service_management' => true, 'knowledge_management' => true, - 'student_and_prospect_portal' => true, + 'event_management' => true, + 'realtime_chat' => true, + 'mobileApps' => true, ], ] ); diff --git a/package.json b/package.json index a189c50282..3b3beb6502 100644 --- a/package.json +++ b/package.json @@ -8,10 +8,11 @@ "build:js-compile": "node ./bin/build.js", "build:filament": "php artisan filament:assets", "build:vite": "vite build", - "build": "npm run build:js-compile && npm run build:vite && npm run build:filament && npm run build:application && npm run build:form && npm run build:survey", "build:application": "(cd widgets/application && vite build)", "build:form": "(cd widgets/form && vite build)", "build:survey": "(cd widgets/survey && vite build)", + "build:event-registration": "(cd widgets/event-registration && vite build)", + "build": "npm run build:js-compile && npm run build:vite && npm run build:filament && npm run build:application && npm run build:form && npm run build:survey && npm run build:event-registration", "api-docs:generate": "export NODE_OPTIONS=--max_old_space_size=4096 && env-cmd spectaql spectaql.yml" }, "devDependencies": { diff --git a/widgets/event-registration/postcss.config.js b/widgets/event-registration/postcss.config.js new file mode 100644 index 0000000000..2f7f96d2ff --- /dev/null +++ b/widgets/event-registration/postcss.config.js @@ -0,0 +1,42 @@ +/* + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ +export default { + plugins: { + 'tailwindcss/nesting': {}, + tailwindcss: { + config: './tailwind.config.js', + }, + autoprefixer: {}, + }, +} diff --git a/widgets/event-registration/src/App.vue b/widgets/event-registration/src/App.vue new file mode 100644 index 0000000000..da5a68bd65 --- /dev/null +++ b/widgets/event-registration/src/App.vue @@ -0,0 +1,363 @@ + + + + diff --git a/widgets/event-registration/src/formkit.config.js b/widgets/event-registration/src/formkit.config.js new file mode 100644 index 0000000000..26e2877b28 --- /dev/null +++ b/widgets/event-registration/src/formkit.config.js @@ -0,0 +1,47 @@ +/* + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ +import { generateClasses } from '@formkit/themes'; +import { genesisIcons } from '@formkit/icons'; +import theme from '../../form/src/FormKit/theme'; +import inputs from '../../form/src/FormKit/Inputs/index'; + +export default { + icons: { + ...genesisIcons, + }, + inputs, + config: { + classes: generateClasses(theme), + }, +}; diff --git a/widgets/event-registration/src/widget.css b/widgets/event-registration/src/widget.css new file mode 100644 index 0000000000..e896335f42 --- /dev/null +++ b/widgets/event-registration/src/widget.css @@ -0,0 +1,38 @@ +/* + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ +@import '../../form/src/FormKit/index.css'; + +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/widgets/event-registration/src/widget.js b/widgets/event-registration/src/widget.js new file mode 100644 index 0000000000..53f8f4e47d --- /dev/null +++ b/widgets/event-registration/src/widget.js @@ -0,0 +1,62 @@ +/* + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ +import { createApp, defineCustomElement, getCurrentInstance, h } from "vue"; +import "./widget.css"; +import App from "./App.vue"; +import { defaultConfig, plugin } from "@formkit/vue"; +import config from "./formkit.config.js"; +import VueSignaturePad from "vue-signature-pad"; + +customElements.define( + 'event-registration-embed', + defineCustomElement({ + setup(props) { + const app = createApp(); + + // install plugins + app.use(plugin, defaultConfig(config)); + + app.use(VueSignaturePad); + + app.config.devtools = true; + + const inst = getCurrentInstance(); + Object.assign(inst.appContext, app._context); + Object.assign(inst.provides, app._context.provides); + + return () => h(App, props); + }, + props: ['url'], + }), +); diff --git a/widgets/event-registration/tailwind.config.js b/widgets/event-registration/tailwind.config.js new file mode 100644 index 0000000000..9ab2129136 --- /dev/null +++ b/widgets/event-registration/tailwind.config.js @@ -0,0 +1,39 @@ +/* + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ +import preset from './tailwind.config.preset.js'; + +export default { + presets: [preset], + content: ['./src/**/*.vue', './src/FormKit/theme.js'], +}; diff --git a/widgets/event-registration/tailwind.config.preset.js b/widgets/event-registration/tailwind.config.preset.js new file mode 100644 index 0000000000..f65aaf5496 --- /dev/null +++ b/widgets/event-registration/tailwind.config.preset.js @@ -0,0 +1,69 @@ +/* + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ +import forms from '@tailwindcss/forms'; +import typography from '@tailwindcss/typography'; +import FormKitVariants from '@formkit/themes/tailwindcss'; + +export default { + theme: { + extend: { + colors: { + primary: { + 50: 'rgba(var(--primary-50), )', + 100: 'rgba(var(--primary-100), )', + 200: 'rgba(var(--primary-200), )', + 300: 'rgba(var(--primary-300), )', + 400: 'rgba(var(--primary-400), )', + 500: 'rgba(var(--primary-500), )', + 600: 'rgba(var(--primary-600), )', + 700: 'rgba(var(--primary-700), )', + 800: 'rgba(var(--primary-800), )', + 900: 'rgba(var(--primary-900), )', + 950: 'rgba(var(--primary-950), )', + }, + }, + borderRadius: { + sm: 'var(--rounding-sm)', + DEFAULT: 'var(--rounding)', + md: 'var(--rounding-md)', + lg: 'var(--rounding-lg)', + full: 'var(--rounding-sm)', + }, + fontFamily: { + signature: ['Satisfy', 'cursive'], + }, + }, + }, + plugins: [forms, typography, FormKitVariants], +} diff --git a/widgets/event-registration/vite.config.js b/widgets/event-registration/vite.config.js new file mode 100644 index 0000000000..72ee5f9760 --- /dev/null +++ b/widgets/event-registration/vite.config.js @@ -0,0 +1,58 @@ +/* + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ +import { resolve } from "path"; +import { defineConfig } from "vite"; +import vue from "@vitejs/plugin-vue"; + +export default defineConfig({ + plugins: [vue()], + build: { + manifest: true, + lib: { + entry: resolve(__dirname, 'src/widget.js'), + name: 'AdvisingAppEventRegistrationFormWidget', + fileName: 'advising-app-event-registration-form-widget', + formats: ['es'], + }, + outDir: resolve(__dirname, '../../public/js/widgets/events'), + emptyOutDir: true, + sourcemap: true, + }, + resolve: { + alias: { + '@': resolve(__dirname, 'src'), + }, + }, + define: { 'process.env.NODE_ENV': '"production"' }, +});