From ef6995d96b49956378e626db6b06a5601e8df180 Mon Sep 17 00:00:00 2001 From: Nuwan Jaliyagoda Date: Fri, 19 Jul 2024 22:53:32 +0530 Subject: [PATCH] Release 0.9.1 (#348) --- .env.example | 15 +- .env.sqlite | 132 + .gitattributes | 0 .githooks/pre-push | 5 + .github/workflows/laravel.yml | 61 +- .github/workflows/laravel_push.yml | 31 + .gitignore | 8 +- .php_cs | 0 .prettierrc.json | 6 + .run/Migrate.run.xml | 10 + .run/Serve.run.xml | 10 + .run/Test.run.xml | 5 + .styleci.yml | 0 .tsconfig | 14 + README.md | 83 +- Start.sh | 19 + app/Console/Kernel.php | 52 + .../Announcement/Models/Announcement.php | 18 + .../Models/Traits/Scope/AnnouncementScope.php | 0 .../Services/AnnouncementService.php | 0 app/Domains/Auth/Events/Role/RoleCreated.php | 0 app/Domains/Auth/Events/Role/RoleDeleted.php | 0 app/Domains/Auth/Events/Role/RoleUpdated.php | 0 app/Domains/Auth/Events/User/UserCreated.php | 0 app/Domains/Auth/Events/User/UserDeleted.php | 0 .../Auth/Events/User/UserDestroyed.php | 0 app/Domains/Auth/Events/User/UserLoggedIn.php | 0 app/Domains/Auth/Events/User/UserRestored.php | 0 .../Auth/Events/User/UserStatusChanged.php | 0 app/Domains/Auth/Events/User/UserUpdated.php | 0 .../Backend/Role/RoleController.php | 0 .../User/DeactivatedUserController.php | 0 .../Backend/User/DeletedUserController.php | 0 .../Backend/User/UserController.php | 0 .../Backend/User/UserPasswordController.php | 0 .../Backend/User/UserSessionController.php | 0 .../Auth/ConfirmPasswordController.php | 0 ...sableTwoFactorAuthenticationController.php | 0 .../Auth/ForgotPasswordController.php | 0 .../Frontend/Auth/LoginController.php | 0 .../Auth/PasswordExpiredController.php | 0 .../Frontend/Auth/RegisterController.php | 3 +- .../Frontend/Auth/ResetPasswordController.php | 0 .../Frontend/Auth/SocialController.php | 0 .../TwoFactorAuthenticationController.php | 0 .../Auth/UpdatePasswordController.php | 0 .../Frontend/Auth/VerificationController.php | 0 .../Auth/Http/Middleware/AdminCheck.php | 0 .../Auth/Http/Middleware/EditabilityCheck.php | 28 + .../Auth/Http/Middleware/PasswordExpires.php | 0 .../Auth/Http/Middleware/SuperAdminCheck.php | 0 .../Auth/Http/Middleware/ToBeLoggedOut.php | 0 .../TwoFactorAuthenticationStatus.php | 0 .../Auth/Http/Middleware/UserCheck.php | 0 .../Auth/Http/Middleware/UserTypeCheck.php | 0 .../Backend/Role/DeleteRoleRequest.php | 0 .../Requests/Backend/Role/EditRoleRequest.php | 0 .../Backend/Role/StoreRoleRequest.php | 2 +- .../Backend/Role/UpdateRoleRequest.php | 4 +- .../Backend/User/ClearUserSessionRequest.php | 0 .../Backend/User/DeleteUserRequest.php | 0 .../Backend/User/EditUserPasswordRequest.php | 0 .../Requests/Backend/User/EditUserRequest.php | 0 .../Backend/User/StoreUserRequest.php | 2 +- .../User/UpdateUserPasswordRequest.php | 0 .../Backend/User/UpdateUserRequest.php | 2 +- .../DisableTwoFactorAuthenticationRequest.php | 0 .../Frontend/Auth/UpdatePasswordRequest.php | 0 .../Auth/Listeners/RoleEventListener.php | 0 .../Auth/Listeners/UserEventListener.php | 0 app/Domains/Auth/Models/PasswordHistory.php | 0 app/Domains/Auth/Models/Permission.php | 0 app/Domains/Auth/Models/Role.php | 0 .../Models/Traits/Attribute/RoleAttribute.php | 0 .../Models/Traits/Attribute/UserAttribute.php | 0 .../Auth/Models/Traits/Method/RoleMethod.php | 0 .../Auth/Models/Traits/Method/UserMethod.php | 41 +- .../Relationship/PermissionRelationship.php | 0 .../Traits/Relationship/UserRelationship.php | 0 .../Models/Traits/Scope/PermissionScope.php | 0 .../Auth/Models/Traits/Scope/RoleScope.php | 0 .../Auth/Models/Traits/Scope/UserScope.php | 30 + app/Domains/Auth/Models/User.php | 10 + .../Frontend/ResetPasswordNotification.php | 0 .../Notifications/Frontend/VerifyEmail.php | 0 app/Domains/Auth/Observers/UserObserver.php | 0 app/Domains/Auth/Rules/UnusedPassword.php | 0 .../Auth/Services/PermissionService.php | 0 app/Domains/Auth/Services/RoleService.php | 0 app/Domains/Auth/Services/UserService.php | 0 app/Exceptions/GeneralException.php | 0 app/Exceptions/Handler.php | 0 app/Exceptions/ReportableException.php | 0 app/Helpers/Global/GeneralHelper.php | 8 +- app/Helpers/Global/HtmlHelper.php | 0 app/Helpers/Global/LocaleHelper.php | 0 app/Helpers/Global/SystemHelper.php | 0 app/Helpers/Global/TimezoneHelper.php | 0 app/Helpers/Global/_readme.txt | 0 .../Controllers/Api/Auth/AuthController.php | 131 + .../Controllers/Api/Auth/OrderController.php | 86 + .../Api/ComponentItemController.php | 223 + .../Api/ComponentTypeController.php | 191 + .../Api/EquipmentItemController.php | 229 + .../Api/EquipmentTypeController.php | 191 + app/Http/Controllers/Api/OrderController.php | 146 + app/Http/Controllers/Api/SearchController.php | 38 + app/Http/Controllers/Auth/LoginController.php | 0 .../Controllers/Auth/RegisterController.php | 0 .../Auth/VerificationController.php | 0 .../Backend/AnnouncementController.php | 120 + .../Backend/ComponentItemController.php | 67 +- .../Backend/ComponentTypeController.php | 19 +- .../Backend/ConsumableItemController.php | 215 + .../Backend/ConsumableTypeController.php | 169 + .../Backend/DashboardController.php | 12 +- .../Backend/EquipmentItemController.php | 68 +- .../Backend/EquipmentTypeController.php | 24 +- .../Backend/JobRequestsController.php | 233 + .../Backend/LocationsController.php | 145 + .../Backend/MachinesController.php | 197 + .../Controllers/Backend/OrderController.php | 139 + .../Backend/RawMaterialsController.php | 208 + .../Backend/ReservationController.php | 365 + .../Controllers/Backend/SearchController.php | 105 + .../Controllers/Backend/StationController.php | 176 + app/Http/Controllers/Controller.php | 66 + .../Frontend/CalendarController.php | 243 + .../Controllers/Frontend/ComponentView.php | 17 +- .../Controllers/Frontend/ConsumableView.php | 44 + .../Controllers/Frontend/EquipmentView.php | 20 +- .../Controllers/Frontend/HomeController.php | 0 .../Controllers/Frontend/SearchController.php | 39 + .../Frontend/StationController.php | 66 + .../Controllers/Frontend/TermsController.php | 0 .../Frontend/User/AccountController.php | 0 .../Frontend/User/CartController.php | 105 + .../Frontend/User/DashboardController.php | 2 +- .../Frontend/User/ProfileController.php | 0 app/Http/Controllers/LocaleController.php | 0 app/Http/Controllers/LocationAPI.php | 41 + app/Http/Kernel.php | 18 +- .../Livewire/Backend/AnnouncementTable.php | 69 + .../Livewire/Backend/ComponentItemTable.php | 62 + .../Livewire/Backend/ComponentTypeTable.php | 36 + .../Livewire/Backend/ConsumableItemTable.php | 63 + .../Livewire/Backend/ConsumableTypeTable.php | 36 + .../Livewire/Backend/EquipmentItemTable.php | 82 + .../Livewire/Backend/EquipmentTypeTable.php | 36 + ...tionsSupervisorPendingFabricationTable.php | 42 + .../Backend/FabricationsTechOfficerTable.php | 46 + .../Backend/FabricationsUserTable.php | 42 + ...tionsWaitingForSupervisorApprovalTable.php | 43 + app/Http/Livewire/Backend/LocationsTable.php | 55 + .../Livewire/Backend/LocationsToggler.php | 50 + app/Http/Livewire/Backend/MachinesTable.php | 66 + .../Livewire/Backend/RawMaterialsTable.php | 56 + app/Http/Livewire/Backend/RolesTable.php | 0 app/Http/Livewire/Backend/StationsTable.php | 36 + app/Http/Livewire/Backend/UsersTable.php | 5 +- .../Frontend/TwoFactorAuthentication.php | 6 +- app/Http/Livewire/LocationsToggler.php | 41 + app/Http/Middleware/Authenticate.php | 0 .../Middleware/CheckForMaintenanceMode.php | 0 app/Http/Middleware/EncryptCookies.php | 0 app/Http/Middleware/LocaleMiddleware.php | 0 .../Middleware/RedirectIfAuthenticated.php | 0 app/Http/Middleware/TrimStrings.php | 0 app/Http/Middleware/TrustHosts.php | 0 app/Http/Middleware/TrustProxies.php | 0 app/Http/Middleware/VerifyCsrfToken.php | 0 .../Frontend/User/UpdateProfileRequest.php | 0 app/Mail/ReservationReminder.php | 41 + app/Mail/StationReservationMail.php | 47 + app/Models/Cart.php | 15 + app/Models/ComponentItem.php | 26 +- app/Models/ComponentItemOrder.php | 14 + app/Models/ComponentType.php | 36 +- app/Models/ConsumableItem.php | 45 + app/Models/ConsumableType.php | 75 + app/Models/EquipmentItem.php | 22 +- app/Models/EquipmentType.php | 41 +- app/Models/ItemLocations.php | 52 + app/Models/JobRequests.php | 84 + app/Models/Locations.php | 53 + app/Models/Machines.php | 123 + app/Models/Order.php | 43 + app/Models/RawMaterials.php | 100 + app/Models/Reservation.php | 44 + app/Models/Stations.php | 25 + app/Models/Traits/Uuid.php | 0 app/Policies/OrderPolicy.php | 94 + app/Providers/AppServiceProvider.php | 4 + app/Providers/AuthServiceProvider.php | 16 + app/Providers/BladeServiceProvider.php | 0 app/Providers/BroadcastServiceProvider.php | 0 app/Providers/ComposerServiceProvider.php | 0 app/Providers/EventServiceProvider.php | 0 app/Providers/HelperServiceProvider.php | 0 app/Providers/LocaleServiceProvider.php | 0 app/Providers/ObserverServiceProvider.php | 0 app/Providers/RouteServiceProvider.php | 5 +- app/Rules/Captcha.php | 0 app/Rules/ValidateAsInternalEmail.php | 44 + app/Services/BaseService.php | 0 app/Services/DepartmentDataService.php | 63 + artisan | 0 bootstrap/app.php | 0 composer.json | 18 +- config/activitylog.php | 0 config/app.php | 3 +- config/auth.php | 2 +- config/boilerplate.php | 0 config/broadcasting.php | 0 config/cache.php | 0 config/constants.php | 11 + config/cors.php | 0 config/database.php | 0 config/discord-logger.php | 61 + config/filesystems.php | 0 config/geoip.php | 0 config/hashing.php | 0 config/livewire-tables.php | 2 +- config/livewire.php | 0 config/lockout.php | 0 config/log-viewer.php | 0 config/logging.php | 9 +- config/mail.php | 0 config/permission.php | 0 config/queue.php | 0 config/sanctum.php | 51 + config/services.php | 0 config/session.php | 0 config/timezone.php | 0 config/view.php | 0 database/.gitignore | 0 database/factories/AnnouncementFactory.php | 0 database/factories/ComponentItemFactory.php | 10 +- database/factories/ComponentTypeFactory.php | 0 database/factories/ConsumableItemFactory.php | 32 + database/factories/ConsumableTypeFactory.php | 25 + database/factories/EquipmentItemFactory.php | 0 database/factories/EquipmentTypeFactory.php | 0 database/factories/ItemLocationsFactory.php | 26 + database/factories/JobRequestsFactory.php | 47 + database/factories/LocationsFactory.php | 24 + database/factories/MachinesFactory.php | 41 + database/factories/OrderFactory.php | 36 + database/factories/RawMaterialsFactory.php | 35 + database/factories/ReservationFactory.php | 34 + database/factories/RoleFactory.php | 2 +- database/factories/StationsFactory.php | 32 + database/factories/UserFactory.php | 38 +- .../2014_10_12_000000_create_users_table.php | 6 +- ...12_100000_create_password_resets_table.php | 0 ..._08_19_000000_create_failed_jobs_table.php | 0 ...01_create_personal_access_tokens_table.php | 36 + ..._02_25_034148_create_permission_tables.php | 8 +- ...5_25_021239_create_announcements_table.php | 0 ...020244_create_password_histories_table.php | 0 ...07_06_215139_create_activity_log_table.php | 0 ...reate_two_factor_authentications_table.php | 0 ...28_190229_create_equipment_types_table.php | 0 ...28_190230_create_equipment_items_table.php | 0 ...26_174701_create_component_types_table.php | 0 ...28_190230_create_component_items_table.php | 31 +- .../2021_09_20_202557_create_orders_table.php | 43 + ...0808_create_component_item_order_table.php | 51 + ...021_10_22_054544_create_machines_table.php | 46 + ...0_22_054722_create_raw_materials_table.php | 41 + ...10_22_054803_create_job_requests_table.php | 71 + ...6_060603_create_consumable_types_table.php | 37 + ...7_021752_create_consumable_items_table.php | 53 + ...22_06_19_093341_create_locations_table.php | 36 + ..._19_104802_create_item_locations_table.php | 37 + ...022_06_22_091455_create_stations_table.php | 35 + ...06_22_123753_create_reservations_table.php | 56 + database/seeders/AnnouncementSeeder.php | 0 .../seeders/Auth/PermissionRoleSeeder.php | 61 +- database/seeders/Auth/UserRoleSeeder.php | 9 + database/seeders/Auth/UserSeeder.php | 31 +- database/seeders/AuthSeeder.php | 0 database/seeders/ComponentItemSeeder.php | 8 +- database/seeders/ComponentTypeSeeder.php | 72 +- database/seeders/ConsumableItemSeeder.php | 306 + database/seeders/ConsumableTypeSeeder.php | 62 + database/seeders/DatabaseSeeder.php | 14 +- database/seeders/EquipmentItemSeeder.php | 257 +- database/seeders/EquipmentTypeSeeder.php | 25 +- database/seeders/ItemLocationsSeeder.php | 218 + database/seeders/JobRequestsSeeder.php | 35 + database/seeders/LocationsSeeder.php | 68 + database/seeders/MachinesSeeder.php | 34 + database/seeders/OrderSeeder.php | 35 + database/seeders/RawMaterialsSeeder.php | 39 + database/seeders/ReservationsSeeder.php | 38 + database/seeders/StationsSeeder.php | 39 + .../seeders/Traits/DisableForeignKeys.php | 0 database/seeders/Traits/TruncateTable.php | 0 package.json | 19 +- phpunit.xml | 0 public/.htaccess | 0 public/css/app.css | 0 public/dummy/item_thumbnail.jpg | Bin 0 -> 2840 bytes public/favicon.ico | 0 public/img/component_items/comit1002.jpg | Bin 5009 -> 0 bytes public/img/equipment_items/1628134056.jpg | Bin public/img/equipment_types/1628188944.jpg | Bin 33159 -> 0 bytes public/img/equipment_types/1628189004.jpg | Bin 36623 -> 0 bytes public/img/equipment_types/1628189057.jpg | Bin 47372 -> 0 bytes public/img/equipment_types/1628189116.jpg | Bin 37103 -> 0 bytes public/img/equipment_types/1628189206.png | Bin 130415 -> 0 bytes public/img/equipment_types/1628189260.jpg | Bin 31702 -> 0 bytes public/img/equipment_types/1629005722.jpg | Bin public/img/equipment_types/1629006269.jpg | Bin public/img/equipment_types/1629006425.jpg | Bin 22202 -> 0 bytes public/img/equipment_types/1629006847.jpg | Bin 25139 -> 0 bytes public/img/equipment_types/1629008372.jpg | Bin public/img/equipment_types/1629008575.jpg | Bin public/img/equipment_types/1629008659.jpg | Bin public/img/equipment_types/1630091609.jpg | Bin public/index.php | 0 public/js/app.js | 0 public/mix-manifest.json | 12 +- public/robots.txt | 0 public/web.config | 0 .../consumable_item_migrations_generator.py | 640 ++ python_scripts/item_locations.py | 223 + python_scripts/output | Bin 0 -> 27884 bytes resources/js/backend/app.js | 0 resources/js/bootstrap.js | 0 resources/js/frontend/app.js | 15 +- .../frontend/components/ExampleComponent.vue | 11 - .../frontend/components/ScheduleCalendar.vue | 274 + resources/js/plugins.js | 0 resources/lang/en/auth.php | 0 resources/lang/en/pagination.php | 0 resources/lang/en/passwords.php | 0 resources/lang/en/validation.php | 0 resources/sass/_global.scss | 0 resources/sass/app.scss | 0 resources/sass/backend/app.scss | 3 +- resources/sass/backend/backend.css | 0 resources/sass/frontend/_global.scss | 0 resources/sass/frontend/_variables.scss | 0 resources/sass/frontend/app.scss | 7 +- resources/sass/frontend/frontend.css | 0 .../backend/announcements/create.blade.php | 101 + .../backend/announcements/delete.blade.php | 27 + .../backend/announcements/edit.blade.php | 102 + .../announcements/index-table-row.blade.php | 42 + .../backend/announcements/index.blade.php | 31 + .../partials/permission-type.blade.php | 0 .../includes/partials/role-type.blade.php | 0 .../auth/includes/permissions.blade.php | 13 + .../backend/auth/includes/roles.blade.php | 12 + .../views/backend/auth/role/create.blade.php | 3 + .../views/backend/auth/role/edit.blade.php | 3 + .../auth/role/includes/actions.blade.php | 0 .../auth/role/includes/children.blade.php | 0 .../includes/no-permissions-message.blade.php | 0 .../backend/auth/role/includes/row.blade.php | 6 + .../views/backend/auth/role/index.blade.php | 0 .../auth/user/change-password.blade.php | 0 .../views/backend/auth/user/create.blade.php | 3 + .../backend/auth/user/deactivated.blade.php | 0 .../views/backend/auth/user/deleted.blade.php | 0 .../views/backend/auth/user/edit.blade.php | 3 + .../backend/auth/user/includes/2fa.blade.php | 0 .../auth/user/includes/actions.blade.php | 0 .../user/includes/breadcrumb-links.blade.php | 0 .../backend/auth/user/includes/row.blade.php | 4 +- .../auth/user/includes/status.blade.php | 0 .../backend/auth/user/includes/type.blade.php | 6 + .../auth/user/includes/verified.blade.php | 0 .../views/backend/auth/user/index.blade.php | 0 .../views/backend/auth/user/show.blade.php | 0 .../includes/breadcrumb-links.blade.php | 8 - .../views/backend/component/index.blade.php | 0 .../backend/component/items/create.blade.php | 60 +- .../backend/component/items/delete.blade.php | 0 .../component/items/edit-location.blade.php | 36 + .../backend/component/items/edit.blade.php | 58 +- .../component/items/index-table-row.blade.php | 37 + .../backend/component/items/index.blade.php | 67 +- .../backend/component/items/show.blade.php | 66 +- .../backend/component/types/create.blade.php | 6 +- .../backend/component/types/delete.blade.php | 0 .../backend/component/types/edit.blade.php | 6 +- .../component/types/index-table-row.blade.php | 42 + .../backend/component/types/index.blade.php | 95 +- .../backend/component/types/show.blade.php | 57 +- .../includes/breadcrumb-links.blade.php | 16 + .../views/backend/consumable/index.blade.php | 23 + .../backend/consumable/items/create.blade.php | 137 + .../backend/consumable/items/delete.blade.php | 32 + .../consumable/items/edit-location.blade.php | 36 + .../backend/consumable/items/edit.blade.php | 135 + .../items/index-table-row.blade.php | 49 + .../backend/consumable/items/index.blade.php | 37 + .../backend/consumable/items/show.blade.php | 132 + .../backend/consumable/types/create.blade.php | 98 + .../backend/consumable/types/delete.blade.php | 32 + .../backend/consumable/types/edit.blade.php | 99 + .../types/index-table-row.blade.php | 38 + .../backend/consumable/types/index.blade.php | 36 + .../backend/consumable/types/show.blade.php | 97 + resources/views/backend/dashboard.blade.php | 47 +- .../includes/breadcrumb-links.blade.php | 2 - .../views/backend/equipment/index.blade.php | 0 .../backend/equipment/items/create.blade.php | 14 +- .../backend/equipment/items/delete.blade.php | 2 +- .../equipment/items/edit-location.blade.php | 36 + .../backend/equipment/items/edit.blade.php | 0 .../equipment/items/index-table-row.blade.php | 59 + .../backend/equipment/items/index.blade.php | 71 +- .../backend/equipment/items/show.blade.php | 24 +- .../backend/equipment/types/create.blade.php | 0 .../backend/equipment/types/delete.blade.php | 0 .../backend/equipment/types/edit.blade.php | 0 .../equipment/types/index-table-row.blade.php | 39 + .../backend/equipment/types/index.blade.php | 69 +- .../backend/equipment/types/show.blade.php | 8 +- .../views/backend/includes/footer.blade.php | 0 .../views/backend/includes/header.blade.php | 10 +- .../includes/partials/breadcrumbs.blade.php | 2 +- .../views/backend/includes/sidebar.blade.php | 260 +- resources/views/backend/jobs/index.blade.php | 41 + .../backend/jobs/student/confirm.blade.php | 106 + .../backend/jobs/student/create.blade.php | 108 + .../backend/jobs/student/delete.blade.php | 40 + .../backend/jobs/student/index.blade.php | 35 + .../views/backend/jobs/student/show.blade.php | 179 + .../jobs/student/student-table-row.blade.php | 52 + .../backend/jobs/supervisor/index.blade.php | 35 + .../pending-fabrication-table-row.blade.php | 35 + .../backend/jobs/supervisor/show.blade.php | 186 + ...or-supervisor-approval-table-row.blade.php | 43 + .../jobs/technical-officer/edit.blade.php | 24 + .../jobs/technical-officer/index.blade.php | 29 + .../jobs/technical-officer/show.blade.php | 24 + .../technical-officer/table-row.blade.php | 54 + resources/views/backend/layouts/app.blade.php | 67 +- .../views/backend/locations/create.blade.php | 46 + .../views/backend/locations/delete.blade.php | 31 + .../views/backend/locations/edit.blade.php | 45 + .../locations/index-table-row.blade.php | 25 + .../views/backend/locations/index.blade.php | 58 + .../views/backend/machines/create.blade.php | 152 + .../views/backend/machines/delete.blade.php | 32 + .../backend/machines/edit-location.blade.php | 37 + .../views/backend/machines/edit.blade.php | 153 + .../includes/breadcrumb-links.blade.php | 10 + .../machines/index-table-row.blade.php | 50 + .../views/backend/machines/index.blade.php | 36 + .../views/backend/machines/show.blade.php | 118 + .../views/backend/orders/create.blade.php | 221 + .../views/backend/orders/delete.blade.php | 0 resources/views/backend/orders/edit.blade.php | 0 .../includes/breadcrumb-links.blade.php | 7 + .../views/backend/orders/index.blade.php | 116 + resources/views/backend/orders/show.blade.php | 105 + ...tion-hierarchy-for-edit-location.blade.php | 13 + .../backend/raw_materials/create.blade.php | 130 + .../backend/raw_materials/delete.blade.php | 34 + .../raw_materials/edit-location.blade.php | 36 + .../backend/raw_materials/edit.blade.php | 131 + .../includes/breadcrumb-links.blade.php | 10 + .../raw_materials/index-table-row.blade.php | 40 + .../backend/raw_materials/index.blade.php | 36 + .../backend/raw_materials/show.blade.php | 102 + .../views/backend/reservation/edit.blade.php | 62 + .../includes/breadcrumb-links.blade.php | 4 + .../views/backend/reservation/index.blade.php | 87 + .../backend/reservation/indexmain.blade.php | 25 + .../views/backend/reservation/show.blade.php | 130 + .../user/breadcrumb-links.blade.php | 6 + .../backend/reservation/user/delete.blade.php | 34 + .../backend/reservation/user/edit.blade.php | 109 + .../backend/reservation/user/index.blade.php | 94 + .../backend/reservation/user/show.blade.php | 129 + .../views/backend/search/index.blade.php | 49 + .../views/backend/search/results.blade.php | 48 + .../backend/search/reverseIndex.blade.php | 48 + .../backend/search/reverseResults.blade.php | 67 + .../views/backend/station/create.blade.php | 83 + .../views/backend/station/delete.blade.php | 32 + .../views/backend/station/edit.blade.php | 83 + .../includes/breadcrumb-links.blade.php | 5 + .../backend/station/index-table-row.blade.php | 33 + .../views/backend/station/index.blade.php | 74 + .../views/backend/station/indexmain.blade.php | 27 + .../views/backend/station/show.blade.php | 62 + .../backend/station/user/index.blade.php | 62 + .../views/backend/station/user/show.blade.php | 48 + .../views/components/backend/card.blade.php | 0 .../views/components/forms/delete.blade.php | 0 .../views/components/forms/get.blade.php | 0 .../views/components/forms/patch.blade.php | 0 .../views/components/forms/post.blade.php | 0 .../views/components/frontend/card.blade.php | 0 .../two-factor-authentication.blade.php | 0 .../views/components/utils/alert.blade.php | 17 +- .../components/utils/delete-button.blade.php | 0 .../components/utils/edit-button.blade.php | 0 .../components/utils/form-button.blade.php | 0 .../views/components/utils/link.blade.php | 0 .../components/utils/view-button.blade.php | 0 .../reservation/reservationmade.blade.php | 17 + .../reservation/reservationreminder.blade.php | 16 + resources/views/errors/401.blade.php | 0 resources/views/errors/403.blade.php | 0 resources/views/errors/404.blade.php | 0 resources/views/errors/419.blade.php | 0 resources/views/errors/429.blade.php | 0 resources/views/errors/500.blade.php | 0 resources/views/errors/503.blade.php | 0 .../views/errors/illustrated-layout.blade.php | 0 resources/views/errors/layout.blade.php | 0 resources/views/errors/minimal.blade.php | 0 .../frontend/auth/includes/social.blade.php | 0 resources/views/frontend/auth/login.blade.php | 0 .../frontend/auth/passwords/confirm.blade.php | 0 .../frontend/auth/passwords/email.blade.php | 0 .../frontend/auth/passwords/expired.blade.php | 0 .../frontend/auth/passwords/reset.blade.php | 0 .../views/frontend/auth/register.blade.php | 0 .../views/frontend/auth/verify.blade.php | 0 .../views/frontend/calendar/index.blade.php | 766 ++ .../frontend/calendar/index_old.blade.php | 338 + .../views/frontend/component/all.blade.php | 39 + .../frontend/component/category.blade.php | 55 +- .../views/frontend/component/index.blade.php | 55 +- .../views/frontend/component/item.blade.php | 97 +- .../views/frontend/consumable/all.blade.php | 40 + .../frontend/consumable/category.blade.php | 73 + .../views/frontend/consumable/index.blade.php | 44 + .../views/frontend/consumable/item.blade.php | 147 + .../views/frontend/equipment/all.blade.php | 40 + .../frontend/equipment/category.blade.php | 54 +- .../views/frontend/equipment/index.blade.php | 52 +- .../views/frontend/equipment/item.blade.php | 115 +- .../views/frontend/includes/nav.blade.php | 89 +- .../includes/partials/breadcrumbs.blade.php | 4 +- resources/views/frontend/index.blade.php | 176 +- .../views/frontend/layouts/app.blade.php | 14 +- .../frontend/layouts/cart_view.blade.php | 100 + .../views/frontend/orders/index.blade.php | 52 + .../views/frontend/pages/terms.blade.php | 0 .../views/frontend/search/results.blade.php | 122 + .../views/frontend/stations/index.blade.php | 55 + .../views/frontend/stations/station.blade.php | 154 + .../views/frontend/user/account.blade.php | 8 +- .../user/account/tabs/information.blade.php | 0 .../user/account/tabs/password.blade.php | 0 .../user/account/tabs/profile.blade.php | 0 .../tabs/two-factor-authentication.blade.php | 0 .../disable.blade.php | 0 .../enable.blade.php | 0 .../recovery.blade.php | 0 resources/views/frontend/user/cart.blade.php | 112 + .../views/frontend/user/dashboard.blade.php | 21 - .../views/frontend/user/overview.blade.php | 35 + .../views/frontend/user/products.blade.php | 26 + .../includes/partials/announcements.blade.php | 2 +- .../views/includes/partials/lang.blade.php | 0 .../includes/partials/logged-in-as.blade.php | 0 .../includes/partials/messages.blade.php | 20 +- .../includes/partials/read-only.blade.php | 0 .../livewire/locations-toggler.blade.php | 26 + .../views/vendor/laraguard/auth.blade.php | 0 .../log-viewer/bootstrap-4/_master.blade.php | 0 routes.txt | 817 ++ routes/api.php | 24 +- routes/api/auth.php | 25 + routes/api/components.php | 65 + routes/api/equipments.php | 67 + routes/api/order.php | 19 + routes/api/search.php | 6 + routes/backend/admin.php | 12 - routes/backend/announcements.php | 54 + routes/backend/auth.php | 4 +- routes/backend/component.php | 288 +- routes/backend/consumables.php | 154 + routes/backend/equipment.php | 284 +- routes/backend/job.php | 161 + routes/backend/locations.php | 55 + routes/backend/machines.php | 73 + routes/backend/order.php | 65 + routes/backend/raw_materials.php | 74 + routes/backend/reservations.php | 65 + routes/backend/search.php | 33 + routes/backend/stations.php | 72 + routes/channels.php | 0 routes/console.php | 0 routes/frontend/auth.php | 6 +- routes/frontend/component.php | 45 +- routes/frontend/consumable.php | 68 + routes/frontend/equipments.php | 68 +- routes/frontend/home.php | 0 routes/frontend/reservations.php | 77 + routes/frontend/search.php | 11 + routes/frontend/stations.php | 51 + routes/frontend/user.php | 23 +- routes/web.php | 16 +- scripts/serve.sh | 0 scripts/setup.sh | 0 scripts/update.sh | 0 server.php | 0 storage/app/.gitignore | 0 storage/app/public/.gitignore | 0 storage/debugbar/.gitignore | 0 storage/framework/.gitignore | 0 storage/framework/cache/.gitignore | 0 storage/framework/cache/data/.gitignore | 0 storage/framework/sessions/.gitignore | 0 storage/framework/testing/.gitignore | 0 storage/framework/views/.gitignore | 0 tests/CreatesApplication.php | 0 tests/Feature/Api/Auth/AuthControllerTest.php | 146 + .../Announcements/AnnouncementTest.php | 111 + .../Backend/Component/ComponentItemTest.php | 78 +- .../Backend/Component/ComponentTypeTest.php | 21 +- .../Backend/Consumable/ConsumableItemTest.php | 183 + .../Backend/Consumable/ConsumableTypeTest.php | 114 + tests/Feature/Backend/DashboardTest.php | 15 +- .../Backend/Equipment/EquipmentItemTest.php | 80 +- .../Backend/Equipment/EquipmentTypeTest.php | 21 +- .../Backend/JobRequests/JobRequests.php | 13 + .../LocationService/LocationServiceTest.php | 183 + .../LocationService/LocationsMenuTest.php | 104 + .../LocationsTogglerLivewireTest.php | 385 + .../Feature/Backend/Machines/MachineTest.php | 125 + .../RawMaterials/RawMaterialItemTest.php | 123 + tests/Feature/Backend/Role/CreateRoleTest.php | 10 +- tests/Feature/Backend/Role/DeleteRoleTest.php | 8 +- tests/Feature/Backend/Role/ListRoleTest.php | 4 +- tests/Feature/Backend/Role/UpdateRoleTest.php | 14 +- .../Backend/Search/NormalSearchTest.php | 229 + .../Backend/Search/ReverseSearchTest.php | 198 + .../Station/ReservationDetailsTest.php | 41 + .../Backend/Station/StationDetailsTest.php | 68 + .../Backend/User/ChangeUserPasswordTest.php | 26 +- .../Feature/Backend/User/ClearSessionTest.php | 6 +- tests/Feature/Backend/User/CreateUserTest.php | 12 +- .../User/DeactivateReactivateUserTest.php | 16 +- tests/Feature/Backend/User/DeleteUserTest.php | 18 +- tests/Feature/Backend/User/ListUserTest.php | 8 +- tests/Feature/Backend/User/UpdateUserTest.php | 16 +- tests/Feature/Frontend/AnnouncementTest.php | 6 +- tests/Feature/Frontend/ChangePasswordTest.php | 0 tests/Feature/Frontend/ComponentTest.php | 40 +- tests/Feature/Frontend/ConfirmationTest.php | 0 .../Frontend/Consumables/ConsumableTest.php | 80 + tests/Feature/Frontend/DashboardTest.php | 0 tests/Feature/Frontend/EquipmentTest.php | 43 +- tests/Feature/Frontend/HomeTest.php | 0 .../Frontend/Homepage/HomepageTest.php | 55 + tests/Feature/Frontend/LocationAPITest.php | 100 + tests/Feature/Frontend/LoginTest.php | 0 tests/Feature/Frontend/LogoutTest.php | 0 .../Frontend/PasswordExpirationTest.php | 2 +- tests/Feature/Frontend/RegistrationTest.php | 14 +- tests/Feature/Frontend/ResetPasswordTest.php | 0 .../Station/ReservationDetailsTest.php | 27 + .../Frontend/Station/StationDetailsTest.php | 49 + tests/Feature/Frontend/UserAccountTest.php | 0 tests/Feature/Frontend/VerificationTest.php | 2 +- .../Feature/Middleware/SwitchLanguageTest.php | 0 .../Feature/Middleware/ToBeLoggedOutTest.php | 0 .../Services/DepartmentDataServiceTest.php | 17 + tests/TestCase.php | 0 webpack.mix.js | 0 yarn.lock | 9829 +++++++++-------- 674 files changed, 29025 insertions(+), 6567 deletions(-) mode change 100644 => 100755 .env.example create mode 100755 .env.sqlite mode change 100644 => 100755 .gitattributes create mode 100755 .githooks/pre-push mode change 100644 => 100755 .github/workflows/laravel.yml create mode 100755 .github/workflows/laravel_push.yml mode change 100644 => 100755 .gitignore mode change 100644 => 100755 .php_cs create mode 100755 .prettierrc.json create mode 100755 .run/Migrate.run.xml create mode 100755 .run/Serve.run.xml create mode 100755 .run/Test.run.xml mode change 100644 => 100755 .styleci.yml create mode 100755 .tsconfig mode change 100644 => 100755 README.md create mode 100755 Start.sh mode change 100644 => 100755 app/Console/Kernel.php mode change 100644 => 100755 app/Domains/Announcement/Models/Announcement.php mode change 100644 => 100755 app/Domains/Announcement/Models/Traits/Scope/AnnouncementScope.php mode change 100644 => 100755 app/Domains/Announcement/Services/AnnouncementService.php mode change 100644 => 100755 app/Domains/Auth/Events/Role/RoleCreated.php mode change 100644 => 100755 app/Domains/Auth/Events/Role/RoleDeleted.php mode change 100644 => 100755 app/Domains/Auth/Events/Role/RoleUpdated.php mode change 100644 => 100755 app/Domains/Auth/Events/User/UserCreated.php mode change 100644 => 100755 app/Domains/Auth/Events/User/UserDeleted.php mode change 100644 => 100755 app/Domains/Auth/Events/User/UserDestroyed.php mode change 100644 => 100755 app/Domains/Auth/Events/User/UserLoggedIn.php mode change 100644 => 100755 app/Domains/Auth/Events/User/UserRestored.php mode change 100644 => 100755 app/Domains/Auth/Events/User/UserStatusChanged.php mode change 100644 => 100755 app/Domains/Auth/Events/User/UserUpdated.php mode change 100644 => 100755 app/Domains/Auth/Http/Controllers/Backend/Role/RoleController.php mode change 100644 => 100755 app/Domains/Auth/Http/Controllers/Backend/User/DeactivatedUserController.php mode change 100644 => 100755 app/Domains/Auth/Http/Controllers/Backend/User/DeletedUserController.php mode change 100644 => 100755 app/Domains/Auth/Http/Controllers/Backend/User/UserController.php mode change 100644 => 100755 app/Domains/Auth/Http/Controllers/Backend/User/UserPasswordController.php mode change 100644 => 100755 app/Domains/Auth/Http/Controllers/Backend/User/UserSessionController.php mode change 100644 => 100755 app/Domains/Auth/Http/Controllers/Frontend/Auth/ConfirmPasswordController.php mode change 100644 => 100755 app/Domains/Auth/Http/Controllers/Frontend/Auth/DisableTwoFactorAuthenticationController.php mode change 100644 => 100755 app/Domains/Auth/Http/Controllers/Frontend/Auth/ForgotPasswordController.php mode change 100644 => 100755 app/Domains/Auth/Http/Controllers/Frontend/Auth/LoginController.php mode change 100644 => 100755 app/Domains/Auth/Http/Controllers/Frontend/Auth/PasswordExpiredController.php mode change 100644 => 100755 app/Domains/Auth/Http/Controllers/Frontend/Auth/RegisterController.php mode change 100644 => 100755 app/Domains/Auth/Http/Controllers/Frontend/Auth/ResetPasswordController.php mode change 100644 => 100755 app/Domains/Auth/Http/Controllers/Frontend/Auth/SocialController.php mode change 100644 => 100755 app/Domains/Auth/Http/Controllers/Frontend/Auth/TwoFactorAuthenticationController.php mode change 100644 => 100755 app/Domains/Auth/Http/Controllers/Frontend/Auth/UpdatePasswordController.php mode change 100644 => 100755 app/Domains/Auth/Http/Controllers/Frontend/Auth/VerificationController.php mode change 100644 => 100755 app/Domains/Auth/Http/Middleware/AdminCheck.php create mode 100755 app/Domains/Auth/Http/Middleware/EditabilityCheck.php mode change 100644 => 100755 app/Domains/Auth/Http/Middleware/PasswordExpires.php mode change 100644 => 100755 app/Domains/Auth/Http/Middleware/SuperAdminCheck.php mode change 100644 => 100755 app/Domains/Auth/Http/Middleware/ToBeLoggedOut.php mode change 100644 => 100755 app/Domains/Auth/Http/Middleware/TwoFactorAuthenticationStatus.php mode change 100644 => 100755 app/Domains/Auth/Http/Middleware/UserCheck.php mode change 100644 => 100755 app/Domains/Auth/Http/Middleware/UserTypeCheck.php mode change 100644 => 100755 app/Domains/Auth/Http/Requests/Backend/Role/DeleteRoleRequest.php mode change 100644 => 100755 app/Domains/Auth/Http/Requests/Backend/Role/EditRoleRequest.php mode change 100644 => 100755 app/Domains/Auth/Http/Requests/Backend/Role/StoreRoleRequest.php mode change 100644 => 100755 app/Domains/Auth/Http/Requests/Backend/Role/UpdateRoleRequest.php mode change 100644 => 100755 app/Domains/Auth/Http/Requests/Backend/User/ClearUserSessionRequest.php mode change 100644 => 100755 app/Domains/Auth/Http/Requests/Backend/User/DeleteUserRequest.php mode change 100644 => 100755 app/Domains/Auth/Http/Requests/Backend/User/EditUserPasswordRequest.php mode change 100644 => 100755 app/Domains/Auth/Http/Requests/Backend/User/EditUserRequest.php mode change 100644 => 100755 app/Domains/Auth/Http/Requests/Backend/User/StoreUserRequest.php mode change 100644 => 100755 app/Domains/Auth/Http/Requests/Backend/User/UpdateUserPasswordRequest.php mode change 100644 => 100755 app/Domains/Auth/Http/Requests/Backend/User/UpdateUserRequest.php mode change 100644 => 100755 app/Domains/Auth/Http/Requests/Frontend/Auth/DisableTwoFactorAuthenticationRequest.php mode change 100644 => 100755 app/Domains/Auth/Http/Requests/Frontend/Auth/UpdatePasswordRequest.php mode change 100644 => 100755 app/Domains/Auth/Listeners/RoleEventListener.php mode change 100644 => 100755 app/Domains/Auth/Listeners/UserEventListener.php mode change 100644 => 100755 app/Domains/Auth/Models/PasswordHistory.php mode change 100644 => 100755 app/Domains/Auth/Models/Permission.php mode change 100644 => 100755 app/Domains/Auth/Models/Role.php mode change 100644 => 100755 app/Domains/Auth/Models/Traits/Attribute/RoleAttribute.php mode change 100644 => 100755 app/Domains/Auth/Models/Traits/Attribute/UserAttribute.php mode change 100644 => 100755 app/Domains/Auth/Models/Traits/Method/RoleMethod.php mode change 100644 => 100755 app/Domains/Auth/Models/Traits/Method/UserMethod.php mode change 100644 => 100755 app/Domains/Auth/Models/Traits/Relationship/PermissionRelationship.php mode change 100644 => 100755 app/Domains/Auth/Models/Traits/Relationship/UserRelationship.php mode change 100644 => 100755 app/Domains/Auth/Models/Traits/Scope/PermissionScope.php mode change 100644 => 100755 app/Domains/Auth/Models/Traits/Scope/RoleScope.php mode change 100644 => 100755 app/Domains/Auth/Models/Traits/Scope/UserScope.php mode change 100644 => 100755 app/Domains/Auth/Models/User.php mode change 100644 => 100755 app/Domains/Auth/Notifications/Frontend/ResetPasswordNotification.php mode change 100644 => 100755 app/Domains/Auth/Notifications/Frontend/VerifyEmail.php mode change 100644 => 100755 app/Domains/Auth/Observers/UserObserver.php mode change 100644 => 100755 app/Domains/Auth/Rules/UnusedPassword.php mode change 100644 => 100755 app/Domains/Auth/Services/PermissionService.php mode change 100644 => 100755 app/Domains/Auth/Services/RoleService.php mode change 100644 => 100755 app/Domains/Auth/Services/UserService.php mode change 100644 => 100755 app/Exceptions/GeneralException.php mode change 100644 => 100755 app/Exceptions/Handler.php mode change 100644 => 100755 app/Exceptions/ReportableException.php mode change 100644 => 100755 app/Helpers/Global/GeneralHelper.php mode change 100644 => 100755 app/Helpers/Global/HtmlHelper.php mode change 100644 => 100755 app/Helpers/Global/LocaleHelper.php mode change 100644 => 100755 app/Helpers/Global/SystemHelper.php mode change 100644 => 100755 app/Helpers/Global/TimezoneHelper.php mode change 100644 => 100755 app/Helpers/Global/_readme.txt create mode 100755 app/Http/Controllers/Api/Auth/AuthController.php create mode 100755 app/Http/Controllers/Api/Auth/OrderController.php create mode 100755 app/Http/Controllers/Api/ComponentItemController.php create mode 100755 app/Http/Controllers/Api/ComponentTypeController.php create mode 100755 app/Http/Controllers/Api/EquipmentItemController.php create mode 100755 app/Http/Controllers/Api/EquipmentTypeController.php create mode 100755 app/Http/Controllers/Api/OrderController.php create mode 100755 app/Http/Controllers/Api/SearchController.php mode change 100644 => 100755 app/Http/Controllers/Auth/LoginController.php mode change 100644 => 100755 app/Http/Controllers/Auth/RegisterController.php mode change 100644 => 100755 app/Http/Controllers/Auth/VerificationController.php create mode 100755 app/Http/Controllers/Backend/AnnouncementController.php mode change 100644 => 100755 app/Http/Controllers/Backend/ComponentItemController.php mode change 100644 => 100755 app/Http/Controllers/Backend/ComponentTypeController.php create mode 100755 app/Http/Controllers/Backend/ConsumableItemController.php create mode 100755 app/Http/Controllers/Backend/ConsumableTypeController.php mode change 100644 => 100755 app/Http/Controllers/Backend/DashboardController.php mode change 100644 => 100755 app/Http/Controllers/Backend/EquipmentItemController.php mode change 100644 => 100755 app/Http/Controllers/Backend/EquipmentTypeController.php create mode 100755 app/Http/Controllers/Backend/JobRequestsController.php create mode 100755 app/Http/Controllers/Backend/LocationsController.php create mode 100755 app/Http/Controllers/Backend/MachinesController.php create mode 100755 app/Http/Controllers/Backend/OrderController.php create mode 100755 app/Http/Controllers/Backend/RawMaterialsController.php create mode 100755 app/Http/Controllers/Backend/ReservationController.php create mode 100755 app/Http/Controllers/Backend/SearchController.php create mode 100755 app/Http/Controllers/Backend/StationController.php mode change 100644 => 100755 app/Http/Controllers/Controller.php create mode 100755 app/Http/Controllers/Frontend/CalendarController.php mode change 100644 => 100755 app/Http/Controllers/Frontend/ComponentView.php create mode 100755 app/Http/Controllers/Frontend/ConsumableView.php mode change 100644 => 100755 app/Http/Controllers/Frontend/EquipmentView.php mode change 100644 => 100755 app/Http/Controllers/Frontend/HomeController.php create mode 100755 app/Http/Controllers/Frontend/SearchController.php create mode 100755 app/Http/Controllers/Frontend/StationController.php mode change 100644 => 100755 app/Http/Controllers/Frontend/TermsController.php mode change 100644 => 100755 app/Http/Controllers/Frontend/User/AccountController.php create mode 100755 app/Http/Controllers/Frontend/User/CartController.php mode change 100644 => 100755 app/Http/Controllers/Frontend/User/DashboardController.php mode change 100644 => 100755 app/Http/Controllers/Frontend/User/ProfileController.php mode change 100644 => 100755 app/Http/Controllers/LocaleController.php create mode 100755 app/Http/Controllers/LocationAPI.php mode change 100644 => 100755 app/Http/Kernel.php create mode 100755 app/Http/Livewire/Backend/AnnouncementTable.php create mode 100755 app/Http/Livewire/Backend/ComponentItemTable.php create mode 100755 app/Http/Livewire/Backend/ComponentTypeTable.php create mode 100755 app/Http/Livewire/Backend/ConsumableItemTable.php create mode 100755 app/Http/Livewire/Backend/ConsumableTypeTable.php create mode 100755 app/Http/Livewire/Backend/EquipmentItemTable.php create mode 100755 app/Http/Livewire/Backend/EquipmentTypeTable.php create mode 100755 app/Http/Livewire/Backend/FabricationsSupervisorPendingFabricationTable.php create mode 100755 app/Http/Livewire/Backend/FabricationsTechOfficerTable.php create mode 100755 app/Http/Livewire/Backend/FabricationsUserTable.php create mode 100755 app/Http/Livewire/Backend/FabricationsWaitingForSupervisorApprovalTable.php create mode 100755 app/Http/Livewire/Backend/LocationsTable.php create mode 100755 app/Http/Livewire/Backend/LocationsToggler.php create mode 100755 app/Http/Livewire/Backend/MachinesTable.php create mode 100755 app/Http/Livewire/Backend/RawMaterialsTable.php mode change 100644 => 100755 app/Http/Livewire/Backend/RolesTable.php create mode 100755 app/Http/Livewire/Backend/StationsTable.php mode change 100644 => 100755 app/Http/Livewire/Backend/UsersTable.php mode change 100644 => 100755 app/Http/Livewire/Frontend/TwoFactorAuthentication.php create mode 100755 app/Http/Livewire/LocationsToggler.php mode change 100644 => 100755 app/Http/Middleware/Authenticate.php mode change 100644 => 100755 app/Http/Middleware/CheckForMaintenanceMode.php mode change 100644 => 100755 app/Http/Middleware/EncryptCookies.php mode change 100644 => 100755 app/Http/Middleware/LocaleMiddleware.php mode change 100644 => 100755 app/Http/Middleware/RedirectIfAuthenticated.php mode change 100644 => 100755 app/Http/Middleware/TrimStrings.php mode change 100644 => 100755 app/Http/Middleware/TrustHosts.php mode change 100644 => 100755 app/Http/Middleware/TrustProxies.php mode change 100644 => 100755 app/Http/Middleware/VerifyCsrfToken.php mode change 100644 => 100755 app/Http/Requests/Frontend/User/UpdateProfileRequest.php create mode 100755 app/Mail/ReservationReminder.php create mode 100755 app/Mail/StationReservationMail.php create mode 100755 app/Models/Cart.php mode change 100644 => 100755 app/Models/ComponentItem.php create mode 100755 app/Models/ComponentItemOrder.php mode change 100644 => 100755 app/Models/ComponentType.php create mode 100755 app/Models/ConsumableItem.php create mode 100755 app/Models/ConsumableType.php mode change 100644 => 100755 app/Models/EquipmentItem.php mode change 100644 => 100755 app/Models/EquipmentType.php create mode 100755 app/Models/ItemLocations.php create mode 100755 app/Models/JobRequests.php create mode 100755 app/Models/Locations.php create mode 100755 app/Models/Machines.php create mode 100755 app/Models/Order.php create mode 100755 app/Models/RawMaterials.php create mode 100755 app/Models/Reservation.php create mode 100755 app/Models/Stations.php mode change 100644 => 100755 app/Models/Traits/Uuid.php create mode 100755 app/Policies/OrderPolicy.php mode change 100644 => 100755 app/Providers/AppServiceProvider.php mode change 100644 => 100755 app/Providers/AuthServiceProvider.php mode change 100644 => 100755 app/Providers/BladeServiceProvider.php mode change 100644 => 100755 app/Providers/BroadcastServiceProvider.php mode change 100644 => 100755 app/Providers/ComposerServiceProvider.php mode change 100644 => 100755 app/Providers/EventServiceProvider.php mode change 100644 => 100755 app/Providers/HelperServiceProvider.php mode change 100644 => 100755 app/Providers/LocaleServiceProvider.php mode change 100644 => 100755 app/Providers/ObserverServiceProvider.php mode change 100644 => 100755 app/Providers/RouteServiceProvider.php mode change 100644 => 100755 app/Rules/Captcha.php create mode 100755 app/Rules/ValidateAsInternalEmail.php mode change 100644 => 100755 app/Services/BaseService.php create mode 100755 app/Services/DepartmentDataService.php mode change 100644 => 100755 artisan mode change 100644 => 100755 bootstrap/app.php mode change 100644 => 100755 composer.json mode change 100644 => 100755 config/activitylog.php mode change 100644 => 100755 config/app.php mode change 100644 => 100755 config/auth.php mode change 100644 => 100755 config/boilerplate.php mode change 100644 => 100755 config/broadcasting.php mode change 100644 => 100755 config/cache.php create mode 100755 config/constants.php mode change 100644 => 100755 config/cors.php mode change 100644 => 100755 config/database.php create mode 100755 config/discord-logger.php mode change 100644 => 100755 config/filesystems.php mode change 100644 => 100755 config/geoip.php mode change 100644 => 100755 config/hashing.php mode change 100644 => 100755 config/livewire-tables.php mode change 100644 => 100755 config/livewire.php mode change 100644 => 100755 config/lockout.php mode change 100644 => 100755 config/log-viewer.php mode change 100644 => 100755 config/logging.php mode change 100644 => 100755 config/mail.php mode change 100644 => 100755 config/permission.php mode change 100644 => 100755 config/queue.php create mode 100755 config/sanctum.php mode change 100644 => 100755 config/services.php mode change 100644 => 100755 config/session.php mode change 100644 => 100755 config/timezone.php mode change 100644 => 100755 config/view.php mode change 100644 => 100755 database/.gitignore mode change 100644 => 100755 database/factories/AnnouncementFactory.php mode change 100644 => 100755 database/factories/ComponentItemFactory.php mode change 100644 => 100755 database/factories/ComponentTypeFactory.php create mode 100755 database/factories/ConsumableItemFactory.php create mode 100755 database/factories/ConsumableTypeFactory.php mode change 100644 => 100755 database/factories/EquipmentItemFactory.php mode change 100644 => 100755 database/factories/EquipmentTypeFactory.php create mode 100755 database/factories/ItemLocationsFactory.php create mode 100755 database/factories/JobRequestsFactory.php create mode 100755 database/factories/LocationsFactory.php create mode 100755 database/factories/MachinesFactory.php create mode 100755 database/factories/OrderFactory.php create mode 100755 database/factories/RawMaterialsFactory.php create mode 100755 database/factories/ReservationFactory.php mode change 100644 => 100755 database/factories/RoleFactory.php create mode 100755 database/factories/StationsFactory.php mode change 100644 => 100755 database/factories/UserFactory.php mode change 100644 => 100755 database/migrations/2014_10_12_000000_create_users_table.php mode change 100644 => 100755 database/migrations/2014_10_12_100000_create_password_resets_table.php mode change 100644 => 100755 database/migrations/2019_08_19_000000_create_failed_jobs_table.php create mode 100755 database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php mode change 100644 => 100755 database/migrations/2020_02_25_034148_create_permission_tables.php mode change 100644 => 100755 database/migrations/2020_05_25_021239_create_announcements_table.php mode change 100644 => 100755 database/migrations/2020_05_29_020244_create_password_histories_table.php mode change 100644 => 100755 database/migrations/2020_07_06_215139_create_activity_log_table.php mode change 100644 => 100755 database/migrations/2021_04_05_153840_create_two_factor_authentications_table.php mode change 100644 => 100755 database/migrations/2021_07_28_190229_create_equipment_types_table.php mode change 100644 => 100755 database/migrations/2021_07_28_190230_create_equipment_items_table.php mode change 100644 => 100755 database/migrations/2021_08_26_174701_create_component_types_table.php mode change 100644 => 100755 database/migrations/2021_08_28_190230_create_component_items_table.php create mode 100755 database/migrations/2021_09_20_202557_create_orders_table.php create mode 100755 database/migrations/2021_09_22_210808_create_component_item_order_table.php create mode 100755 database/migrations/2021_10_22_054544_create_machines_table.php create mode 100755 database/migrations/2021_10_22_054722_create_raw_materials_table.php create mode 100755 database/migrations/2021_10_22_054803_create_job_requests_table.php create mode 100755 database/migrations/2022_06_06_060603_create_consumable_types_table.php create mode 100755 database/migrations/2022_06_07_021752_create_consumable_items_table.php create mode 100755 database/migrations/2022_06_19_093341_create_locations_table.php create mode 100755 database/migrations/2022_06_19_104802_create_item_locations_table.php create mode 100755 database/migrations/2022_06_22_091455_create_stations_table.php create mode 100755 database/migrations/2022_06_22_123753_create_reservations_table.php mode change 100644 => 100755 database/seeders/AnnouncementSeeder.php mode change 100644 => 100755 database/seeders/Auth/PermissionRoleSeeder.php mode change 100644 => 100755 database/seeders/Auth/UserRoleSeeder.php mode change 100644 => 100755 database/seeders/Auth/UserSeeder.php mode change 100644 => 100755 database/seeders/AuthSeeder.php mode change 100644 => 100755 database/seeders/ComponentItemSeeder.php mode change 100644 => 100755 database/seeders/ComponentTypeSeeder.php create mode 100755 database/seeders/ConsumableItemSeeder.php create mode 100755 database/seeders/ConsumableTypeSeeder.php mode change 100644 => 100755 database/seeders/DatabaseSeeder.php mode change 100644 => 100755 database/seeders/EquipmentItemSeeder.php mode change 100644 => 100755 database/seeders/EquipmentTypeSeeder.php create mode 100755 database/seeders/ItemLocationsSeeder.php create mode 100755 database/seeders/JobRequestsSeeder.php create mode 100755 database/seeders/LocationsSeeder.php create mode 100755 database/seeders/MachinesSeeder.php create mode 100755 database/seeders/OrderSeeder.php create mode 100755 database/seeders/RawMaterialsSeeder.php create mode 100755 database/seeders/ReservationsSeeder.php create mode 100755 database/seeders/StationsSeeder.php mode change 100644 => 100755 database/seeders/Traits/DisableForeignKeys.php mode change 100644 => 100755 database/seeders/Traits/TruncateTable.php mode change 100644 => 100755 package.json mode change 100644 => 100755 phpunit.xml mode change 100644 => 100755 public/.htaccess mode change 100644 => 100755 public/css/app.css create mode 100755 public/dummy/item_thumbnail.jpg mode change 100644 => 100755 public/favicon.ico delete mode 100644 public/img/component_items/comit1002.jpg mode change 100644 => 100755 public/img/equipment_items/1628134056.jpg delete mode 100644 public/img/equipment_types/1628188944.jpg delete mode 100644 public/img/equipment_types/1628189004.jpg delete mode 100644 public/img/equipment_types/1628189057.jpg delete mode 100644 public/img/equipment_types/1628189116.jpg delete mode 100644 public/img/equipment_types/1628189206.png delete mode 100644 public/img/equipment_types/1628189260.jpg mode change 100644 => 100755 public/img/equipment_types/1629005722.jpg mode change 100644 => 100755 public/img/equipment_types/1629006269.jpg delete mode 100644 public/img/equipment_types/1629006425.jpg delete mode 100644 public/img/equipment_types/1629006847.jpg mode change 100644 => 100755 public/img/equipment_types/1629008372.jpg mode change 100644 => 100755 public/img/equipment_types/1629008575.jpg mode change 100644 => 100755 public/img/equipment_types/1629008659.jpg mode change 100644 => 100755 public/img/equipment_types/1630091609.jpg mode change 100644 => 100755 public/index.php mode change 100644 => 100755 public/js/app.js mode change 100644 => 100755 public/mix-manifest.json mode change 100644 => 100755 public/robots.txt mode change 100644 => 100755 public/web.config create mode 100755 python_scripts/consumable_item_migrations_generator.py create mode 100755 python_scripts/item_locations.py create mode 100755 python_scripts/output mode change 100644 => 100755 resources/js/backend/app.js mode change 100644 => 100755 resources/js/bootstrap.js mode change 100644 => 100755 resources/js/frontend/app.js delete mode 100644 resources/js/frontend/components/ExampleComponent.vue create mode 100755 resources/js/frontend/components/ScheduleCalendar.vue mode change 100644 => 100755 resources/js/plugins.js mode change 100644 => 100755 resources/lang/en/auth.php mode change 100644 => 100755 resources/lang/en/pagination.php mode change 100644 => 100755 resources/lang/en/passwords.php mode change 100644 => 100755 resources/lang/en/validation.php mode change 100644 => 100755 resources/sass/_global.scss mode change 100644 => 100755 resources/sass/app.scss mode change 100644 => 100755 resources/sass/backend/app.scss mode change 100644 => 100755 resources/sass/backend/backend.css mode change 100644 => 100755 resources/sass/frontend/_global.scss mode change 100644 => 100755 resources/sass/frontend/_variables.scss mode change 100644 => 100755 resources/sass/frontend/app.scss mode change 100644 => 100755 resources/sass/frontend/frontend.css create mode 100755 resources/views/backend/announcements/create.blade.php create mode 100755 resources/views/backend/announcements/delete.blade.php create mode 100755 resources/views/backend/announcements/edit.blade.php create mode 100755 resources/views/backend/announcements/index-table-row.blade.php create mode 100755 resources/views/backend/announcements/index.blade.php mode change 100644 => 100755 resources/views/backend/auth/includes/partials/permission-type.blade.php mode change 100644 => 100755 resources/views/backend/auth/includes/partials/role-type.blade.php mode change 100644 => 100755 resources/views/backend/auth/includes/permissions.blade.php mode change 100644 => 100755 resources/views/backend/auth/includes/roles.blade.php mode change 100644 => 100755 resources/views/backend/auth/role/create.blade.php mode change 100644 => 100755 resources/views/backend/auth/role/edit.blade.php mode change 100644 => 100755 resources/views/backend/auth/role/includes/actions.blade.php mode change 100644 => 100755 resources/views/backend/auth/role/includes/children.blade.php mode change 100644 => 100755 resources/views/backend/auth/role/includes/no-permissions-message.blade.php mode change 100644 => 100755 resources/views/backend/auth/role/includes/row.blade.php mode change 100644 => 100755 resources/views/backend/auth/role/index.blade.php mode change 100644 => 100755 resources/views/backend/auth/user/change-password.blade.php mode change 100644 => 100755 resources/views/backend/auth/user/create.blade.php mode change 100644 => 100755 resources/views/backend/auth/user/deactivated.blade.php mode change 100644 => 100755 resources/views/backend/auth/user/deleted.blade.php mode change 100644 => 100755 resources/views/backend/auth/user/edit.blade.php mode change 100644 => 100755 resources/views/backend/auth/user/includes/2fa.blade.php mode change 100644 => 100755 resources/views/backend/auth/user/includes/actions.blade.php mode change 100644 => 100755 resources/views/backend/auth/user/includes/breadcrumb-links.blade.php mode change 100644 => 100755 resources/views/backend/auth/user/includes/row.blade.php mode change 100644 => 100755 resources/views/backend/auth/user/includes/status.blade.php mode change 100644 => 100755 resources/views/backend/auth/user/includes/type.blade.php mode change 100644 => 100755 resources/views/backend/auth/user/includes/verified.blade.php mode change 100644 => 100755 resources/views/backend/auth/user/index.blade.php mode change 100644 => 100755 resources/views/backend/auth/user/show.blade.php mode change 100644 => 100755 resources/views/backend/component/includes/breadcrumb-links.blade.php mode change 100644 => 100755 resources/views/backend/component/index.blade.php mode change 100644 => 100755 resources/views/backend/component/items/create.blade.php mode change 100644 => 100755 resources/views/backend/component/items/delete.blade.php create mode 100755 resources/views/backend/component/items/edit-location.blade.php mode change 100644 => 100755 resources/views/backend/component/items/edit.blade.php create mode 100755 resources/views/backend/component/items/index-table-row.blade.php mode change 100644 => 100755 resources/views/backend/component/items/index.blade.php mode change 100644 => 100755 resources/views/backend/component/items/show.blade.php mode change 100644 => 100755 resources/views/backend/component/types/create.blade.php mode change 100644 => 100755 resources/views/backend/component/types/delete.blade.php mode change 100644 => 100755 resources/views/backend/component/types/edit.blade.php create mode 100755 resources/views/backend/component/types/index-table-row.blade.php mode change 100644 => 100755 resources/views/backend/component/types/index.blade.php mode change 100644 => 100755 resources/views/backend/component/types/show.blade.php create mode 100755 resources/views/backend/consumable/includes/breadcrumb-links.blade.php create mode 100755 resources/views/backend/consumable/index.blade.php create mode 100755 resources/views/backend/consumable/items/create.blade.php create mode 100755 resources/views/backend/consumable/items/delete.blade.php create mode 100755 resources/views/backend/consumable/items/edit-location.blade.php create mode 100755 resources/views/backend/consumable/items/edit.blade.php create mode 100755 resources/views/backend/consumable/items/index-table-row.blade.php create mode 100755 resources/views/backend/consumable/items/index.blade.php create mode 100755 resources/views/backend/consumable/items/show.blade.php create mode 100755 resources/views/backend/consumable/types/create.blade.php create mode 100755 resources/views/backend/consumable/types/delete.blade.php create mode 100755 resources/views/backend/consumable/types/edit.blade.php create mode 100755 resources/views/backend/consumable/types/index-table-row.blade.php create mode 100755 resources/views/backend/consumable/types/index.blade.php create mode 100755 resources/views/backend/consumable/types/show.blade.php mode change 100644 => 100755 resources/views/backend/dashboard.blade.php mode change 100644 => 100755 resources/views/backend/equipment/includes/breadcrumb-links.blade.php mode change 100644 => 100755 resources/views/backend/equipment/index.blade.php mode change 100644 => 100755 resources/views/backend/equipment/items/create.blade.php mode change 100644 => 100755 resources/views/backend/equipment/items/delete.blade.php create mode 100755 resources/views/backend/equipment/items/edit-location.blade.php mode change 100644 => 100755 resources/views/backend/equipment/items/edit.blade.php create mode 100755 resources/views/backend/equipment/items/index-table-row.blade.php mode change 100644 => 100755 resources/views/backend/equipment/items/index.blade.php mode change 100644 => 100755 resources/views/backend/equipment/items/show.blade.php mode change 100644 => 100755 resources/views/backend/equipment/types/create.blade.php mode change 100644 => 100755 resources/views/backend/equipment/types/delete.blade.php mode change 100644 => 100755 resources/views/backend/equipment/types/edit.blade.php create mode 100755 resources/views/backend/equipment/types/index-table-row.blade.php mode change 100644 => 100755 resources/views/backend/equipment/types/index.blade.php mode change 100644 => 100755 resources/views/backend/equipment/types/show.blade.php mode change 100644 => 100755 resources/views/backend/includes/footer.blade.php mode change 100644 => 100755 resources/views/backend/includes/header.blade.php mode change 100644 => 100755 resources/views/backend/includes/partials/breadcrumbs.blade.php mode change 100644 => 100755 resources/views/backend/includes/sidebar.blade.php create mode 100755 resources/views/backend/jobs/index.blade.php create mode 100755 resources/views/backend/jobs/student/confirm.blade.php create mode 100755 resources/views/backend/jobs/student/create.blade.php create mode 100755 resources/views/backend/jobs/student/delete.blade.php create mode 100755 resources/views/backend/jobs/student/index.blade.php create mode 100755 resources/views/backend/jobs/student/show.blade.php create mode 100755 resources/views/backend/jobs/student/student-table-row.blade.php create mode 100755 resources/views/backend/jobs/supervisor/index.blade.php create mode 100755 resources/views/backend/jobs/supervisor/pending-fabrication-table-row.blade.php create mode 100755 resources/views/backend/jobs/supervisor/show.blade.php create mode 100755 resources/views/backend/jobs/supervisor/waiting-for-supervisor-approval-table-row.blade.php create mode 100755 resources/views/backend/jobs/technical-officer/edit.blade.php create mode 100755 resources/views/backend/jobs/technical-officer/index.blade.php create mode 100755 resources/views/backend/jobs/technical-officer/show.blade.php create mode 100755 resources/views/backend/jobs/technical-officer/table-row.blade.php mode change 100644 => 100755 resources/views/backend/layouts/app.blade.php create mode 100755 resources/views/backend/locations/create.blade.php create mode 100755 resources/views/backend/locations/delete.blade.php create mode 100755 resources/views/backend/locations/edit.blade.php create mode 100755 resources/views/backend/locations/index-table-row.blade.php create mode 100755 resources/views/backend/locations/index.blade.php create mode 100755 resources/views/backend/machines/create.blade.php create mode 100755 resources/views/backend/machines/delete.blade.php create mode 100755 resources/views/backend/machines/edit-location.blade.php create mode 100755 resources/views/backend/machines/edit.blade.php create mode 100755 resources/views/backend/machines/includes/breadcrumb-links.blade.php create mode 100755 resources/views/backend/machines/index-table-row.blade.php create mode 100755 resources/views/backend/machines/index.blade.php create mode 100755 resources/views/backend/machines/show.blade.php create mode 100755 resources/views/backend/orders/create.blade.php create mode 100755 resources/views/backend/orders/delete.blade.php create mode 100755 resources/views/backend/orders/edit.blade.php create mode 100755 resources/views/backend/orders/includes/breadcrumb-links.blade.php create mode 100755 resources/views/backend/orders/index.blade.php create mode 100755 resources/views/backend/orders/show.blade.php create mode 100755 resources/views/backend/partials/location-hierarchy-for-edit-location.blade.php create mode 100755 resources/views/backend/raw_materials/create.blade.php create mode 100755 resources/views/backend/raw_materials/delete.blade.php create mode 100755 resources/views/backend/raw_materials/edit-location.blade.php create mode 100755 resources/views/backend/raw_materials/edit.blade.php create mode 100755 resources/views/backend/raw_materials/includes/breadcrumb-links.blade.php create mode 100755 resources/views/backend/raw_materials/index-table-row.blade.php create mode 100755 resources/views/backend/raw_materials/index.blade.php create mode 100755 resources/views/backend/raw_materials/show.blade.php create mode 100755 resources/views/backend/reservation/edit.blade.php create mode 100755 resources/views/backend/reservation/includes/breadcrumb-links.blade.php create mode 100755 resources/views/backend/reservation/index.blade.php create mode 100755 resources/views/backend/reservation/indexmain.blade.php create mode 100755 resources/views/backend/reservation/show.blade.php create mode 100755 resources/views/backend/reservation/user/breadcrumb-links.blade.php create mode 100755 resources/views/backend/reservation/user/delete.blade.php create mode 100755 resources/views/backend/reservation/user/edit.blade.php create mode 100755 resources/views/backend/reservation/user/index.blade.php create mode 100755 resources/views/backend/reservation/user/show.blade.php create mode 100755 resources/views/backend/search/index.blade.php create mode 100755 resources/views/backend/search/results.blade.php create mode 100755 resources/views/backend/search/reverseIndex.blade.php create mode 100755 resources/views/backend/search/reverseResults.blade.php create mode 100755 resources/views/backend/station/create.blade.php create mode 100755 resources/views/backend/station/delete.blade.php create mode 100755 resources/views/backend/station/edit.blade.php create mode 100755 resources/views/backend/station/includes/breadcrumb-links.blade.php create mode 100755 resources/views/backend/station/index-table-row.blade.php create mode 100755 resources/views/backend/station/index.blade.php create mode 100755 resources/views/backend/station/indexmain.blade.php create mode 100755 resources/views/backend/station/show.blade.php create mode 100755 resources/views/backend/station/user/index.blade.php create mode 100755 resources/views/backend/station/user/show.blade.php mode change 100644 => 100755 resources/views/components/backend/card.blade.php mode change 100644 => 100755 resources/views/components/forms/delete.blade.php mode change 100644 => 100755 resources/views/components/forms/get.blade.php mode change 100644 => 100755 resources/views/components/forms/patch.blade.php mode change 100644 => 100755 resources/views/components/forms/post.blade.php mode change 100644 => 100755 resources/views/components/frontend/card.blade.php mode change 100644 => 100755 resources/views/components/frontend/two-factor-authentication.blade.php mode change 100644 => 100755 resources/views/components/utils/alert.blade.php mode change 100644 => 100755 resources/views/components/utils/delete-button.blade.php mode change 100644 => 100755 resources/views/components/utils/edit-button.blade.php mode change 100644 => 100755 resources/views/components/utils/form-button.blade.php mode change 100644 => 100755 resources/views/components/utils/link.blade.php mode change 100644 => 100755 resources/views/components/utils/view-button.blade.php create mode 100755 resources/views/emails/reservation/reservationmade.blade.php create mode 100755 resources/views/emails/reservation/reservationreminder.blade.php mode change 100644 => 100755 resources/views/errors/401.blade.php mode change 100644 => 100755 resources/views/errors/403.blade.php mode change 100644 => 100755 resources/views/errors/404.blade.php mode change 100644 => 100755 resources/views/errors/419.blade.php mode change 100644 => 100755 resources/views/errors/429.blade.php mode change 100644 => 100755 resources/views/errors/500.blade.php mode change 100644 => 100755 resources/views/errors/503.blade.php mode change 100644 => 100755 resources/views/errors/illustrated-layout.blade.php mode change 100644 => 100755 resources/views/errors/layout.blade.php mode change 100644 => 100755 resources/views/errors/minimal.blade.php mode change 100644 => 100755 resources/views/frontend/auth/includes/social.blade.php mode change 100644 => 100755 resources/views/frontend/auth/login.blade.php mode change 100644 => 100755 resources/views/frontend/auth/passwords/confirm.blade.php mode change 100644 => 100755 resources/views/frontend/auth/passwords/email.blade.php mode change 100644 => 100755 resources/views/frontend/auth/passwords/expired.blade.php mode change 100644 => 100755 resources/views/frontend/auth/passwords/reset.blade.php mode change 100644 => 100755 resources/views/frontend/auth/register.blade.php mode change 100644 => 100755 resources/views/frontend/auth/verify.blade.php create mode 100755 resources/views/frontend/calendar/index.blade.php create mode 100755 resources/views/frontend/calendar/index_old.blade.php create mode 100755 resources/views/frontend/component/all.blade.php mode change 100644 => 100755 resources/views/frontend/component/category.blade.php mode change 100644 => 100755 resources/views/frontend/component/index.blade.php mode change 100644 => 100755 resources/views/frontend/component/item.blade.php create mode 100755 resources/views/frontend/consumable/all.blade.php create mode 100755 resources/views/frontend/consumable/category.blade.php create mode 100755 resources/views/frontend/consumable/index.blade.php create mode 100755 resources/views/frontend/consumable/item.blade.php create mode 100755 resources/views/frontend/equipment/all.blade.php mode change 100644 => 100755 resources/views/frontend/equipment/category.blade.php mode change 100644 => 100755 resources/views/frontend/equipment/index.blade.php mode change 100644 => 100755 resources/views/frontend/equipment/item.blade.php mode change 100644 => 100755 resources/views/frontend/includes/nav.blade.php mode change 100644 => 100755 resources/views/frontend/includes/partials/breadcrumbs.blade.php mode change 100644 => 100755 resources/views/frontend/index.blade.php mode change 100644 => 100755 resources/views/frontend/layouts/app.blade.php create mode 100755 resources/views/frontend/layouts/cart_view.blade.php create mode 100755 resources/views/frontend/orders/index.blade.php mode change 100644 => 100755 resources/views/frontend/pages/terms.blade.php create mode 100755 resources/views/frontend/search/results.blade.php create mode 100755 resources/views/frontend/stations/index.blade.php create mode 100755 resources/views/frontend/stations/station.blade.php mode change 100644 => 100755 resources/views/frontend/user/account.blade.php mode change 100644 => 100755 resources/views/frontend/user/account/tabs/information.blade.php mode change 100644 => 100755 resources/views/frontend/user/account/tabs/password.blade.php mode change 100644 => 100755 resources/views/frontend/user/account/tabs/profile.blade.php mode change 100644 => 100755 resources/views/frontend/user/account/tabs/two-factor-authentication.blade.php mode change 100644 => 100755 resources/views/frontend/user/account/tabs/two-factor-authentication/disable.blade.php mode change 100644 => 100755 resources/views/frontend/user/account/tabs/two-factor-authentication/enable.blade.php mode change 100644 => 100755 resources/views/frontend/user/account/tabs/two-factor-authentication/recovery.blade.php create mode 100755 resources/views/frontend/user/cart.blade.php delete mode 100644 resources/views/frontend/user/dashboard.blade.php create mode 100755 resources/views/frontend/user/overview.blade.php create mode 100755 resources/views/frontend/user/products.blade.php mode change 100644 => 100755 resources/views/includes/partials/announcements.blade.php mode change 100644 => 100755 resources/views/includes/partials/lang.blade.php mode change 100644 => 100755 resources/views/includes/partials/logged-in-as.blade.php mode change 100644 => 100755 resources/views/includes/partials/messages.blade.php mode change 100644 => 100755 resources/views/includes/partials/read-only.blade.php create mode 100755 resources/views/livewire/locations-toggler.blade.php mode change 100644 => 100755 resources/views/vendor/laraguard/auth.blade.php mode change 100644 => 100755 resources/views/vendor/log-viewer/bootstrap-4/_master.blade.php create mode 100755 routes.txt mode change 100644 => 100755 routes/api.php create mode 100755 routes/api/auth.php create mode 100755 routes/api/components.php create mode 100755 routes/api/equipments.php create mode 100755 routes/api/order.php create mode 100755 routes/api/search.php delete mode 100644 routes/backend/admin.php create mode 100755 routes/backend/announcements.php mode change 100644 => 100755 routes/backend/auth.php mode change 100644 => 100755 routes/backend/component.php create mode 100755 routes/backend/consumables.php mode change 100644 => 100755 routes/backend/equipment.php create mode 100755 routes/backend/job.php create mode 100755 routes/backend/locations.php create mode 100755 routes/backend/machines.php create mode 100755 routes/backend/order.php create mode 100755 routes/backend/raw_materials.php create mode 100755 routes/backend/reservations.php create mode 100755 routes/backend/search.php create mode 100755 routes/backend/stations.php mode change 100644 => 100755 routes/channels.php mode change 100644 => 100755 routes/console.php mode change 100644 => 100755 routes/frontend/auth.php mode change 100644 => 100755 routes/frontend/component.php create mode 100755 routes/frontend/consumable.php mode change 100644 => 100755 routes/frontend/equipments.php mode change 100644 => 100755 routes/frontend/home.php create mode 100755 routes/frontend/reservations.php create mode 100755 routes/frontend/search.php create mode 100755 routes/frontend/stations.php mode change 100644 => 100755 routes/frontend/user.php mode change 100644 => 100755 routes/web.php mode change 100644 => 100755 scripts/serve.sh mode change 100644 => 100755 scripts/setup.sh mode change 100644 => 100755 scripts/update.sh mode change 100644 => 100755 server.php mode change 100644 => 100755 storage/app/.gitignore mode change 100644 => 100755 storage/app/public/.gitignore mode change 100644 => 100755 storage/debugbar/.gitignore mode change 100644 => 100755 storage/framework/.gitignore mode change 100644 => 100755 storage/framework/cache/.gitignore mode change 100644 => 100755 storage/framework/cache/data/.gitignore mode change 100644 => 100755 storage/framework/sessions/.gitignore mode change 100644 => 100755 storage/framework/testing/.gitignore mode change 100644 => 100755 storage/framework/views/.gitignore mode change 100644 => 100755 tests/CreatesApplication.php create mode 100755 tests/Feature/Api/Auth/AuthControllerTest.php create mode 100755 tests/Feature/Backend/Announcements/AnnouncementTest.php mode change 100644 => 100755 tests/Feature/Backend/Component/ComponentItemTest.php mode change 100644 => 100755 tests/Feature/Backend/Component/ComponentTypeTest.php create mode 100755 tests/Feature/Backend/Consumable/ConsumableItemTest.php create mode 100755 tests/Feature/Backend/Consumable/ConsumableTypeTest.php mode change 100644 => 100755 tests/Feature/Backend/DashboardTest.php mode change 100644 => 100755 tests/Feature/Backend/Equipment/EquipmentItemTest.php mode change 100644 => 100755 tests/Feature/Backend/Equipment/EquipmentTypeTest.php create mode 100755 tests/Feature/Backend/JobRequests/JobRequests.php create mode 100755 tests/Feature/Backend/LocationService/LocationServiceTest.php create mode 100755 tests/Feature/Backend/LocationService/LocationsMenuTest.php create mode 100755 tests/Feature/Backend/LocationService/LocationsTogglerLivewireTest.php create mode 100755 tests/Feature/Backend/Machines/MachineTest.php create mode 100755 tests/Feature/Backend/RawMaterials/RawMaterialItemTest.php mode change 100644 => 100755 tests/Feature/Backend/Role/CreateRoleTest.php mode change 100644 => 100755 tests/Feature/Backend/Role/DeleteRoleTest.php mode change 100644 => 100755 tests/Feature/Backend/Role/ListRoleTest.php mode change 100644 => 100755 tests/Feature/Backend/Role/UpdateRoleTest.php create mode 100755 tests/Feature/Backend/Search/NormalSearchTest.php create mode 100755 tests/Feature/Backend/Search/ReverseSearchTest.php create mode 100755 tests/Feature/Backend/Station/ReservationDetailsTest.php create mode 100755 tests/Feature/Backend/Station/StationDetailsTest.php mode change 100644 => 100755 tests/Feature/Backend/User/ChangeUserPasswordTest.php mode change 100644 => 100755 tests/Feature/Backend/User/ClearSessionTest.php mode change 100644 => 100755 tests/Feature/Backend/User/CreateUserTest.php mode change 100644 => 100755 tests/Feature/Backend/User/DeactivateReactivateUserTest.php mode change 100644 => 100755 tests/Feature/Backend/User/DeleteUserTest.php mode change 100644 => 100755 tests/Feature/Backend/User/ListUserTest.php mode change 100644 => 100755 tests/Feature/Backend/User/UpdateUserTest.php mode change 100644 => 100755 tests/Feature/Frontend/AnnouncementTest.php mode change 100644 => 100755 tests/Feature/Frontend/ChangePasswordTest.php mode change 100644 => 100755 tests/Feature/Frontend/ComponentTest.php mode change 100644 => 100755 tests/Feature/Frontend/ConfirmationTest.php create mode 100755 tests/Feature/Frontend/Consumables/ConsumableTest.php mode change 100644 => 100755 tests/Feature/Frontend/DashboardTest.php mode change 100644 => 100755 tests/Feature/Frontend/EquipmentTest.php mode change 100644 => 100755 tests/Feature/Frontend/HomeTest.php create mode 100755 tests/Feature/Frontend/Homepage/HomepageTest.php create mode 100755 tests/Feature/Frontend/LocationAPITest.php mode change 100644 => 100755 tests/Feature/Frontend/LoginTest.php mode change 100644 => 100755 tests/Feature/Frontend/LogoutTest.php mode change 100644 => 100755 tests/Feature/Frontend/PasswordExpirationTest.php mode change 100644 => 100755 tests/Feature/Frontend/RegistrationTest.php mode change 100644 => 100755 tests/Feature/Frontend/ResetPasswordTest.php create mode 100755 tests/Feature/Frontend/Station/ReservationDetailsTest.php create mode 100755 tests/Feature/Frontend/Station/StationDetailsTest.php mode change 100644 => 100755 tests/Feature/Frontend/UserAccountTest.php mode change 100644 => 100755 tests/Feature/Frontend/VerificationTest.php mode change 100644 => 100755 tests/Feature/Middleware/SwitchLanguageTest.php mode change 100644 => 100755 tests/Feature/Middleware/ToBeLoggedOutTest.php create mode 100755 tests/Feature/Services/DepartmentDataServiceTest.php mode change 100644 => 100755 tests/TestCase.php mode change 100644 => 100755 webpack.mix.js mode change 100644 => 100755 yarn.lock diff --git a/.env.example b/.env.example old mode 100644 new mode 100755 index 6517d52a..97dda51d --- a/.env.example +++ b/.env.example @@ -1,15 +1,28 @@ APP_NAME="CE Smart Inventory" + APP_ENV=local +#APP_ENV=production + APP_KEY= APP_DEBUG=true APP_URL=http://localhost -# Login +# Default Login accounts with passwords SEED_ADMIN_EMAIL="admin@admin.com" SEED_ADMIN_PASSWORD="admin_user" + SEED_USER_EMAIL="user@user.com" SEED_USER_PASSWORD="regular_user" +SEED_LECTURER_EMAIL="lecturer@example.com" +SEED_LECTURER_PASSWORD="lecturer_user" + +SEED_TECH_OFFICER_EMAIL="techofficer@example.com" +SEED_TECH_OFFICER_PASSWORD="tech_officer_user" + +SEED_MAINTAINER_EMAIL="maintainer@example.com" +SEED_MAINTAINER_PASSWORD="maintainer_user" + # Misc APP_READ_ONLY=false APP_READ_ONLY_LOGIN=true diff --git a/.env.sqlite b/.env.sqlite new file mode 100755 index 00000000..3911bf5b --- /dev/null +++ b/.env.sqlite @@ -0,0 +1,132 @@ +# Create a file at ./database/database.sqlite +# run command -> touch ./database/database.sqlite +# Then use this env file. No need mysql servers for development +# This could cause problems if the seeders first record has the id = 0, mysql defaults to id=1. Therefore, use mysql +# when creating new tables and seeders + +APP_NAME="CE Smart Inventory" + +APP_ENV=local +#APP_ENV=production + +APP_KEY= +APP_DEBUG=true +APP_URL=http://localhost + +# Default Login accounts with passwords +SEED_ADMIN_EMAIL="admin@admin.com" +SEED_ADMIN_PASSWORD="admin_user" + +SEED_USER_EMAIL="user@user.com" +SEED_USER_PASSWORD="regular_user" + +SEED_LECTURER_EMAIL="lecturer@example.com" +SEED_LECTURER_PASSWORD="lecturer_user" + +SEED_TECH_OFFICER_EMAIL="techofficer@example.com" +SEED_TECH_OFFICER_PASSWORD="tech_officer_user" + +SEED_MAINTAINER_EMAIL="maintainer@example.com" +SEED_MAINTAINER_PASSWORD="maintainer_user" + +# Misc +APP_READ_ONLY=false +APP_READ_ONLY_LOGIN=true +DEBUGBAR_ENABLED=false +LOG_CHANNEL=daily +LOG_LEVEL=debug + +# Drivers +DB_CONNECTION=sqlite +BROADCAST_DRIVER=log +CACHE_DRIVER=file +FILESYSTEM_DRIVER=local +QUEUE_CONNECTION=sync +SESSION_DRIVER=file +SESSION_LIFETIME=120 + +# Database +DB_HOST=127.0.0.1 + +# Cache +MEMCACHED_HOST=127.0.0.1 + +# Queue +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 + +# Mail +MAIL_MAILER=smtp +MAIL_HOST=smtp.mailtrap.io +MAIL_PORT=2525 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null +MAIL_FROM_ADDRESS=null +MAIL_FROM_NAME="${APP_NAME}" + +# AWS +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +AWS_DEFAULT_REGION=us-east-1 +AWS_BUCKET= +AWS_USE_PATH_STYLE_ENDPOINT=false + +# Pusher +PUSHER_APP_ID= +PUSHER_APP_KEY= +PUSHER_APP_SECRET= +PUSHER_APP_CLUSTER=mt1 + +MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" +MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" + +# Application + +# Access +ADMIN_REQUIRES_2FA=true +CHANGE_EMAIL=true +ENABLE_REGISTRATION=true +PASSWORD_HISTORY=3 +SINGLE_LOGIN=false +PASSWORD_EXPIRES_DAYS=180 + +# Captcha +# Get your credentials at: https://www.google.com/recaptcha/admin +LOGIN_CAPTCHA_STATUS=false +REGISTRATION_CAPTCHA_STATUS=false +INVISIBLE_RECAPTCHA_SITEKEY= +INVISIBLE_RECAPTCHA_SECRETKEY= + +# Socialite Providers +FACEBOOK_ACTIVE=false +BITBUCKET_ACTIVE=false +GITHUB_ACTIVE=false +GOOGLE_ACTIVE=false +LINKEDIN_ACTIVE=false +TWITTER_ACTIVE=false + +#FACEBOOK_CLIENT_ID= +#FACEBOOK_CLIENT_SECRET= +#FACEBOOK_REDIRECT=${APP_URL}/login/facebook/callback + +#BITBUCKET_CLIENT_ID= +#BITBUCKET_CLIENT_SECRET= +#BITBUCKET_REDIRECT=${APP_URL}/login/bitbucket/callback + +#GITHUB_CLIENT_ID= +#GITHUB_CLIENT_SECRET= +#GITHUB_REDIRECT=${APP_URL}/login/github/callback + +#GOOGLE_CLIENT_ID= +#GOOGLE_CLIENT_SECRET= +#GOOGLE_REDIRECT=${APP_URL}/login/google/callback + +#LINKEDIN_CLIENT_ID= +#LINKEDIN_CLIENT_SECRET= +#LINKEDIN_REDIRECT=${APP_URL}/login/linkedin/callback + +#TWITTER_CLIENT_ID= +#TWITTER_CLIENT_SECRET= +#TWITTER_REDIRECT=${APP_URL}/login/twitter/callback diff --git a/.gitattributes b/.gitattributes old mode 100644 new mode 100755 diff --git a/.githooks/pre-push b/.githooks/pre-push new file mode 100755 index 00000000..6e73b4d5 --- /dev/null +++ b/.githooks/pre-push @@ -0,0 +1,5 @@ +#! /bin/bash + +echo "Git hook executing: pre-commit actions" + +php artisan test -p \ No newline at end of file diff --git a/.github/workflows/laravel.yml b/.github/workflows/laravel.yml old mode 100644 new mode 100755 index 0b68909d..9d735dba --- a/.github/workflows/laravel.yml +++ b/.github/workflows/laravel.yml @@ -1,32 +1,37 @@ name: Laravel -on: [push, pull_request] +on: [pull_request] jobs: - laravel-tests: - - runs-on: ubuntu-latest - - steps: - - uses: shivammathur/setup-php@15c43e89cdef867065b0213be354c2841860869e - with: - php-version: '8.0' - - uses: actions/checkout@v2 - - name: Copy .env - run: php -r "file_exists('.env') || copy('.env.example', '.env');" - - name: Install Dependencies - run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist - - name: Generate key - run: php artisan key:generate - - name: Directory Permissions - run: chmod -R 777 storage bootstrap/cache - - name: Create Database - run: | - mkdir -p database - touch database/database.sqlite - - name: Execute tests (Unit and Feature tests) via PHPUnit - env: - DB_CONNECTION: sqlite - DB_DATABASE: database/database.sqlite - run: | - php artisan test --colors --debug \ No newline at end of file + laravel-tests: + runs-on: ubuntu-latest + + steps: + - uses: shivammathur/setup-php@15c43e89cdef867065b0213be354c2841860869e + with: + php-version: '8.0' + - uses: actions/checkout@v2 + + - name: Copy .env + run: php -r "file_exists('.env') || copy('.env.example', '.env');" + + - name: Install Dependencies + run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist + + - name: Generate key + run: php artisan key:generate + + - name: Directory Permissions + run: chmod -R 777 storage bootstrap/cache + + - name: Create Database + run: | + mkdir -p database + touch database/database.sqlite + + - name: Execute tests (Unit and Feature tests) via PHPUnit + env: + DB_CONNECTION: sqlite + DB_DATABASE: database/database.sqlite + run: | + php artisan test --colors --debug diff --git a/.github/workflows/laravel_push.yml b/.github/workflows/laravel_push.yml new file mode 100755 index 00000000..4c85c75d --- /dev/null +++ b/.github/workflows/laravel_push.yml @@ -0,0 +1,31 @@ +name: Laravel Push Test + +on: [push] + +jobs: + laravel-tests: + runs-on: ubuntu-latest + + steps: + - uses: shivammathur/setup-php@15c43e89cdef867065b0213be354c2841860869e + with: + php-version: '8.0' + - uses: actions/checkout@v2 + - name: Copy .env + run: php -r "file_exists('.env') || copy('.env.example', '.env');" + - name: Install Dependencies + run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist + - name: Generate key + run: php artisan key:generate + - name: Directory Permissions + run: chmod -R 777 storage bootstrap/cache + - name: Create Database + run: | + mkdir -p database + touch database/database.sqlite + - name: Execute tests (Unit and Feature tests) via PHPUnit + env: + DB_CONNECTION: sqlite + DB_DATABASE: database/database.sqlite + run: | + php artisan test -p --colors --debug diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index 18e98e61..96929201 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ /public/hot /public/storage /public/img +/public/files /public/mix-manifest.json /storage/*.key /vendor @@ -16,7 +17,6 @@ _ide_helper.php .DS_Store .env .env.backup -.idea .php_cs.cache .phpunit.result.cache .phpstorm.meta.php @@ -31,5 +31,9 @@ npm-debug.log output.txt Thumbs.db yarn-error.log -package-lock.json +commands.txt composer.lock +notes.txt +package-lock.json +yarn.lock +/.idea diff --git a/.php_cs b/.php_cs old mode 100644 new mode 100755 diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100755 index 00000000..ef58ff9d --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,6 @@ +{ + "trailingComma": "es5", + "tabWidth": 4, + "semi": false, + "singleQuote": true +} diff --git a/.run/Migrate.run.xml b/.run/Migrate.run.xml new file mode 100755 index 00000000..3a10b340 --- /dev/null +++ b/.run/Migrate.run.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.run/Serve.run.xml b/.run/Serve.run.xml new file mode 100755 index 00000000..d684589f --- /dev/null +++ b/.run/Serve.run.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.run/Test.run.xml b/.run/Test.run.xml new file mode 100755 index 00000000..ea7ed3b4 --- /dev/null +++ b/.run/Test.run.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/.styleci.yml b/.styleci.yml old mode 100644 new mode 100755 diff --git a/.tsconfig b/.tsconfig new file mode 100755 index 00000000..96067ed4 --- /dev/null +++ b/.tsconfig @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "module": "system" + }, + "include": [ + "resources/js/frontend/components/*" + ], + "exclude": [ + "node_modules" + ], + "vueCompilerOptions": { + "target": "2.7" + } +} diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 7afe0e86..a3f5d574 --- a/README.md +++ b/README.md @@ -6,12 +6,15 @@ Smart Inventory Management System for Department MakerSpace Lab ### Demo Credentials -**Admin:** admin@admin.com +**Admin:** admin@example.com **Password:** admin_user -**User:** user@user.com +**User:** user@example.com **Password:** regular_user +**User:** lecturer@example.com +**Password:** lecturer_user + ### Introduction Laravel Boilerplate provides you with a massive head start on any size web application. Out of the box it has features like a backend built on CoreUI with Spatie/Permission authorization. It has a frontend scaffold built on Bootstrap 4. Other features such as Two Factor Authentication, User/Role management, searchable/sortable tables built on my [Laravel Livewire tables plugin](https://github.com/rappasoft/laravel-livewire-tables), user impersonation, timezone support, multi-lingual support with 20+ built in languages, demo mode, and much more. @@ -19,11 +22,32 @@ Laravel Boilerplate provides you with a massive head start on any size web appli [Click here for the official documentation](http://laravel-boilerplate.com) ## Team of Developers -- [Nuwan Jaliyagoda](http://github.com/NuwanJ) -- [Tharmapalan Thanujan](http://github.com/thanujan96) -- [Madhushan Ramalingam](https://github.com/DrMadhushan) -- [Thilini Madushani](http://github.com/Thilini98) +- [Nuwan Jaliyagoda](http://github.com/NuwanJ) + +### Sprint 2A + +- [Tharmapalan Thanujan](http://github.com/thanujan96) +- [Madhushan Ramalingam](https://github.com/DrMadhushan) +- [Thilini Madushani](http://github.com/Thilini98) + +### Sprint 3A + +- [Ishan Fernando](https://github.com/ishanfdo18098) +- [Adeepa Fernando](https://github.com/NipunFernando) +- [Ridma Jayasundara ](https://github.com/ridmajayasundara) + +### Sprint 3B + +- [Sadia Jameel](https://github.com/SaadiaJameel) +- [Sakuni Nimnadi](https://github.com/SakuniJayasinghe) +- [Thamish Wanduragala](https://github.com/Thamish99) + +### Sprint 3C + +- [Karan R.](https://github.com/rasathuraikaran) +- [Gowsigan A.](https://github.com/AnnalingamGowsigan) +- [Muthuni De Alwis](https://github.com/muthuni-dealwis) ## Useful Commands and Instructions @@ -31,10 +55,14 @@ You need to install Wamp server and run it before following commands. Please make sure you already created database user account. #### Install Dependencies + ``` // Install PHP dependencies composer install +// If you received mmap() error, use this command +// php -d memory_limit=-1 /usr/local/bin/composer install + // Update PHP dependencies composer update @@ -55,6 +83,9 @@ php artisan migrate // Reset the database and seed the data php artisan migrate:fresh --seed +// Prepare webhook for unit testing +git config --local core.hooksPath .githooks + ``` #### Serve in the local environment @@ -70,7 +101,18 @@ php artisan serve --host=0.0.0.0 --port=8000 npm run watch ``` +#### Run all above commands from bash script + +``` +// Enable execution of bash script (for Linux) +chmod +x Start.sh + +// Run bash script +./Start.sh +``` + #### Cache and optimization + ``` // Remove dev dependencies composer install --optimize-autoloader --no-dev @@ -84,7 +126,8 @@ php artisan route:clear php artisan view:clear ``` -#### Maintenance related commands +#### Maintenance related commands + ``` php artisan down --message="{Message}" --retry=60 php artisan up @@ -105,17 +148,19 @@ php artisan tinker // Run the unit tests php artisan test -``` +// Run unit tests in parallel +php artisan test -p -#### Resource Routes - -|Verb |URI |Action |Route Name | -|:------|:------|:------|:----------| -|GET |/photos/{photo}/comments |index |photos.comments.index| -|GET |/photos/{photo}/comments/create |create |photos.comments.create -|POST |/photos/{photo}/comments |store |photos.comments.store -|GET |/comments/{comment} |show |comments.show -|GET |/comments/{comment}/edit |edit |comments.edit -|PUT/PATCH |/comments/{comment} |update |comments.update -|DELETE |/comments/{comment} |destroy |comments.destroy +``` +#### Resource Routes + +| Verb | URI | Action | Route Name | +| :-------- | :------------------------------ | :------ | :--------------------- | +| GET | /photos/{photo}/comments | index | photos.comments.index | +| GET | /photos/{photo}/comments/create | create | photos.comments.create | +| POST | /photos/{photo}/comments | store | photos.comments.store | +| GET | /comments/{comment} | show | comments.show | +| GET | /comments/{comment}/edit | edit | comments.edit | +| PUT/PATCH | /comments/{comment} | update | comments.update | +| DELETE | /comments/{comment} | destroy | comments.destroy | diff --git a/Start.sh b/Start.sh new file mode 100755 index 00000000..1d2a926c --- /dev/null +++ b/Start.sh @@ -0,0 +1,19 @@ +#! /bin/bash + +echo "Starting ..." +echo "Running : composer install" +composer install +echo "Running : composer update" +composer update +echo "Running : npm install" +npm install +echo "Running : npm run dev" +npm run dev +echo "Running : php artisan storage:link" +php artisan storage:link +echo "Running : php artisan migrate" +php artisan migrate +echo "Running : php artisan migrate:fresh --seed" +php artisan migrate:fresh --seed +echo "Running : php artisan serve" +php artisan serve diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php old mode 100644 new mode 100755 index d4dde018..c6ef9a57 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -2,6 +2,9 @@ namespace App\Console; + +use App\Mail\ReservationReminder; +use Illuminate\Support\Facades\DB; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; @@ -28,6 +31,55 @@ class Kernel extends ConsoleKernel protected function schedule(Schedule $schedule) { // $schedule->command('activitylog:clean')->daily(); + +//*********************Send mails 30 minutes before end time*************************************** + + $schedule->call(function () { + + + $dat=(new DateTime(Carbon::now()->addMinutes(360)))->format('Y-m-d H:i:s'); + $dat2=(new DateTime(Carbon::now()->addMinutes(420)))->format('Y-m-d H:i:s'); + + $bookings = Reservation::where('start_date','<',$dat) + ->where('end_date','>',$dat) + ->where('end_date','<',$dat2) + ->get(); + + foreach($bookings as $booking){ + try{ + $enums = explode(',',$booking->E_numbers); + + foreach ($enums as $enum){ + + //get enumber + $enum1=explode('/',$enum); + $batch=$enum1[1]; + $regnum=$enum1[2]; + + //set api url + $apiurl = 'https://api.ce.pdn.ac.lk/people/v1/students/E'.''.$batch.'/'.$regnum.'/'; + + //api call + $response = Http::withoutVerifying() + ->get($apiurl); + + //extract email address + $email=($response['emails']['faculty']['name'].'@'.$response['emails']['faculty']['domain']); + + //get user + $user = auth()->user(); + + //send mail + Mail::to($email) + ->send(new ReservationReminder($booking, $station)); + } + + }catch(\Exception $e){ + } + } + })->hourly(); + +//******************************************************************************************* */ } /** diff --git a/app/Domains/Announcement/Models/Announcement.php b/app/Domains/Announcement/Models/Announcement.php old mode 100644 new mode 100755 index 50bf50de..207ab8ca --- a/app/Domains/Announcement/Models/Announcement.php +++ b/app/Domains/Announcement/Models/Announcement.php @@ -50,6 +50,24 @@ class Announcement extends Model 'enabled' => 'boolean', ]; + public static function areas() + { + return [ + 'frontend' => 'Frontend', + 'backend' => 'Backend' + ]; + } + + public static function types() + { + return [ + 'info' => 'Info', + 'danger' => 'Danger', + 'warning' => 'Warning', + 'success' => 'Success' + ]; + } + /** * Create a new factory instance for the model. * diff --git a/app/Domains/Announcement/Models/Traits/Scope/AnnouncementScope.php b/app/Domains/Announcement/Models/Traits/Scope/AnnouncementScope.php old mode 100644 new mode 100755 diff --git a/app/Domains/Announcement/Services/AnnouncementService.php b/app/Domains/Announcement/Services/AnnouncementService.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Events/Role/RoleCreated.php b/app/Domains/Auth/Events/Role/RoleCreated.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Events/Role/RoleDeleted.php b/app/Domains/Auth/Events/Role/RoleDeleted.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Events/Role/RoleUpdated.php b/app/Domains/Auth/Events/Role/RoleUpdated.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Events/User/UserCreated.php b/app/Domains/Auth/Events/User/UserCreated.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Events/User/UserDeleted.php b/app/Domains/Auth/Events/User/UserDeleted.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Events/User/UserDestroyed.php b/app/Domains/Auth/Events/User/UserDestroyed.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Events/User/UserLoggedIn.php b/app/Domains/Auth/Events/User/UserLoggedIn.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Events/User/UserRestored.php b/app/Domains/Auth/Events/User/UserRestored.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Events/User/UserStatusChanged.php b/app/Domains/Auth/Events/User/UserStatusChanged.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Events/User/UserUpdated.php b/app/Domains/Auth/Events/User/UserUpdated.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Controllers/Backend/Role/RoleController.php b/app/Domains/Auth/Http/Controllers/Backend/Role/RoleController.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Controllers/Backend/User/DeactivatedUserController.php b/app/Domains/Auth/Http/Controllers/Backend/User/DeactivatedUserController.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Controllers/Backend/User/DeletedUserController.php b/app/Domains/Auth/Http/Controllers/Backend/User/DeletedUserController.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Controllers/Backend/User/UserController.php b/app/Domains/Auth/Http/Controllers/Backend/User/UserController.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Controllers/Backend/User/UserPasswordController.php b/app/Domains/Auth/Http/Controllers/Backend/User/UserPasswordController.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Controllers/Backend/User/UserSessionController.php b/app/Domains/Auth/Http/Controllers/Backend/User/UserSessionController.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Controllers/Frontend/Auth/ConfirmPasswordController.php b/app/Domains/Auth/Http/Controllers/Frontend/Auth/ConfirmPasswordController.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Controllers/Frontend/Auth/DisableTwoFactorAuthenticationController.php b/app/Domains/Auth/Http/Controllers/Frontend/Auth/DisableTwoFactorAuthenticationController.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Controllers/Frontend/Auth/ForgotPasswordController.php b/app/Domains/Auth/Http/Controllers/Frontend/Auth/ForgotPasswordController.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Controllers/Frontend/Auth/LoginController.php b/app/Domains/Auth/Http/Controllers/Frontend/Auth/LoginController.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Controllers/Frontend/Auth/PasswordExpiredController.php b/app/Domains/Auth/Http/Controllers/Frontend/Auth/PasswordExpiredController.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Controllers/Frontend/Auth/RegisterController.php b/app/Domains/Auth/Http/Controllers/Frontend/Auth/RegisterController.php old mode 100644 new mode 100755 index 8e62e96a..29cef289 --- a/app/Domains/Auth/Http/Controllers/Frontend/Auth/RegisterController.php +++ b/app/Domains/Auth/Http/Controllers/Frontend/Auth/RegisterController.php @@ -8,6 +8,7 @@ use Illuminate\Support\Facades\Validator; use Illuminate\Validation\Rule; use LangleyFoxall\LaravelNISTPasswordRules\PasswordRules; +use App\Rules\ValidateAsInternalEmail; /** * Class RegisterController. @@ -74,7 +75,7 @@ protected function validator(array $data) { return Validator::make($data, [ 'name' => ['required', 'string', 'max:100'], - 'email' => ['required', 'string', 'email', 'max:255', Rule::unique('users')], + 'email' => ['required', 'string', 'email', 'max:255', Rule::unique('users'), new ValidateAsInternalEmail()], 'password' => array_merge(['max:100'], PasswordRules::register($data['email'] ?? null)), 'terms' => ['required', 'in:1'], 'g-recaptcha-response' => ['required_if:captcha_status,true', new Captcha], diff --git a/app/Domains/Auth/Http/Controllers/Frontend/Auth/ResetPasswordController.php b/app/Domains/Auth/Http/Controllers/Frontend/Auth/ResetPasswordController.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Controllers/Frontend/Auth/SocialController.php b/app/Domains/Auth/Http/Controllers/Frontend/Auth/SocialController.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Controllers/Frontend/Auth/TwoFactorAuthenticationController.php b/app/Domains/Auth/Http/Controllers/Frontend/Auth/TwoFactorAuthenticationController.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Controllers/Frontend/Auth/UpdatePasswordController.php b/app/Domains/Auth/Http/Controllers/Frontend/Auth/UpdatePasswordController.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Controllers/Frontend/Auth/VerificationController.php b/app/Domains/Auth/Http/Controllers/Frontend/Auth/VerificationController.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Middleware/AdminCheck.php b/app/Domains/Auth/Http/Middleware/AdminCheck.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Middleware/EditabilityCheck.php b/app/Domains/Auth/Http/Middleware/EditabilityCheck.php new file mode 100755 index 00000000..253acfd4 --- /dev/null +++ b/app/Domains/Auth/Http/Middleware/EditabilityCheck.php @@ -0,0 +1,28 @@ +user(); + if ($request->user() && ($user->isType(User::TYPE_ADMIN) || $user->isType(User::TYPE_MAINTAINER) || $user->isType(User::TYPE_TECH_OFFICER))) { + return $next($request); + } + + return redirect()->route('admin.dashboard')->withFlashDanger(__('You do not have access to do that.')); + } +} diff --git a/app/Domains/Auth/Http/Middleware/PasswordExpires.php b/app/Domains/Auth/Http/Middleware/PasswordExpires.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Middleware/SuperAdminCheck.php b/app/Domains/Auth/Http/Middleware/SuperAdminCheck.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Middleware/ToBeLoggedOut.php b/app/Domains/Auth/Http/Middleware/ToBeLoggedOut.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Middleware/TwoFactorAuthenticationStatus.php b/app/Domains/Auth/Http/Middleware/TwoFactorAuthenticationStatus.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Middleware/UserCheck.php b/app/Domains/Auth/Http/Middleware/UserCheck.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Middleware/UserTypeCheck.php b/app/Domains/Auth/Http/Middleware/UserTypeCheck.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Requests/Backend/Role/DeleteRoleRequest.php b/app/Domains/Auth/Http/Requests/Backend/Role/DeleteRoleRequest.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Requests/Backend/Role/EditRoleRequest.php b/app/Domains/Auth/Http/Requests/Backend/Role/EditRoleRequest.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Requests/Backend/Role/StoreRoleRequest.php b/app/Domains/Auth/Http/Requests/Backend/Role/StoreRoleRequest.php old mode 100644 new mode 100755 index 39f0a298..5431b3b0 --- a/app/Domains/Auth/Http/Requests/Backend/Role/StoreRoleRequest.php +++ b/app/Domains/Auth/Http/Requests/Backend/Role/StoreRoleRequest.php @@ -29,7 +29,7 @@ public function authorize() public function rules() { return [ - 'type' => ['required', Rule::in([User::TYPE_ADMIN, User::TYPE_USER])], + 'type' => ['required', Rule::in([User::TYPE_ADMIN, User::TYPE_USER, User::TYPE_LECTURER, User::TYPE_TECH_OFFICER, User::TYPE_MAINTAINER])], 'name' => ['required', 'max:100', Rule::unique('roles')], 'permissions' => ['sometimes', 'array'], 'permissions.*' => [Rule::exists('permissions', 'id')->where('type', $this->type)], diff --git a/app/Domains/Auth/Http/Requests/Backend/Role/UpdateRoleRequest.php b/app/Domains/Auth/Http/Requests/Backend/Role/UpdateRoleRequest.php old mode 100644 new mode 100755 index a0f9bc6a..9ae3f107 --- a/app/Domains/Auth/Http/Requests/Backend/Role/UpdateRoleRequest.php +++ b/app/Domains/Auth/Http/Requests/Backend/Role/UpdateRoleRequest.php @@ -19,7 +19,7 @@ class UpdateRoleRequest extends FormRequest */ public function authorize() { - return ! $this->role->isAdmin(); + return !$this->role->isAdmin(); } /** @@ -30,7 +30,7 @@ public function authorize() public function rules() { return [ - 'type' => ['required', Rule::in([User::TYPE_ADMIN, User::TYPE_USER])], + 'type' => ['required', Rule::in([User::TYPE_ADMIN, User::TYPE_USER, User::TYPE_LECTURER, User::TYPE_TECH_OFFICER, User::TYPE_MAINTAINER])], 'name' => ['required', 'max:100', Rule::unique('roles')->ignore($this->role)], 'permissions' => ['sometimes', 'array'], 'permissions.*' => [Rule::exists('permissions', 'id')->where('type', $this->type)], diff --git a/app/Domains/Auth/Http/Requests/Backend/User/ClearUserSessionRequest.php b/app/Domains/Auth/Http/Requests/Backend/User/ClearUserSessionRequest.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Requests/Backend/User/DeleteUserRequest.php b/app/Domains/Auth/Http/Requests/Backend/User/DeleteUserRequest.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Requests/Backend/User/EditUserPasswordRequest.php b/app/Domains/Auth/Http/Requests/Backend/User/EditUserPasswordRequest.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Requests/Backend/User/EditUserRequest.php b/app/Domains/Auth/Http/Requests/Backend/User/EditUserRequest.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Requests/Backend/User/StoreUserRequest.php b/app/Domains/Auth/Http/Requests/Backend/User/StoreUserRequest.php old mode 100644 new mode 100755 index 71c153e1..136e57df --- a/app/Domains/Auth/Http/Requests/Backend/User/StoreUserRequest.php +++ b/app/Domains/Auth/Http/Requests/Backend/User/StoreUserRequest.php @@ -30,7 +30,7 @@ public function authorize() public function rules() { return [ - 'type' => ['required', Rule::in([User::TYPE_ADMIN, User::TYPE_USER])], + 'type' => ['required', Rule::in([User::TYPE_ADMIN, User::TYPE_USER, User::TYPE_LECTURER, User::TYPE_TECH_OFFICER, User::TYPE_MAINTAINER])], 'name' => ['required', 'max:100'], 'email' => ['required', 'max:255', 'email', Rule::unique('users')], 'password' => ['max:100', PasswordRules::register($this->email)], diff --git a/app/Domains/Auth/Http/Requests/Backend/User/UpdateUserPasswordRequest.php b/app/Domains/Auth/Http/Requests/Backend/User/UpdateUserPasswordRequest.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Requests/Backend/User/UpdateUserRequest.php b/app/Domains/Auth/Http/Requests/Backend/User/UpdateUserRequest.php old mode 100644 new mode 100755 index f9dc6f2f..4256c010 --- a/app/Domains/Auth/Http/Requests/Backend/User/UpdateUserRequest.php +++ b/app/Domains/Auth/Http/Requests/Backend/User/UpdateUserRequest.php @@ -32,7 +32,7 @@ public function rules() return [ 'type' => [Rule::requiredIf(function () { return ! $this->user->isMasterAdmin(); - }), Rule::in([User::TYPE_ADMIN, User::TYPE_USER])], + }), Rule::in([User::TYPE_ADMIN, User::TYPE_USER, User::TYPE_LECTURER, User::TYPE_TECH_OFFICER, User::TYPE_MAINTAINER])], 'name' => ['required', 'max:100'], 'email' => ['required', 'max:255', 'email', Rule::unique('users')->ignore($this->user->id)], 'roles' => ['sometimes', 'array'], diff --git a/app/Domains/Auth/Http/Requests/Frontend/Auth/DisableTwoFactorAuthenticationRequest.php b/app/Domains/Auth/Http/Requests/Frontend/Auth/DisableTwoFactorAuthenticationRequest.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Http/Requests/Frontend/Auth/UpdatePasswordRequest.php b/app/Domains/Auth/Http/Requests/Frontend/Auth/UpdatePasswordRequest.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Listeners/RoleEventListener.php b/app/Domains/Auth/Listeners/RoleEventListener.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Listeners/UserEventListener.php b/app/Domains/Auth/Listeners/UserEventListener.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Models/PasswordHistory.php b/app/Domains/Auth/Models/PasswordHistory.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Models/Permission.php b/app/Domains/Auth/Models/Permission.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Models/Role.php b/app/Domains/Auth/Models/Role.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Models/Traits/Attribute/RoleAttribute.php b/app/Domains/Auth/Models/Traits/Attribute/RoleAttribute.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Models/Traits/Attribute/UserAttribute.php b/app/Domains/Auth/Models/Traits/Attribute/UserAttribute.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Models/Traits/Method/RoleMethod.php b/app/Domains/Auth/Models/Traits/Method/RoleMethod.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Models/Traits/Method/UserMethod.php b/app/Domains/Auth/Models/Traits/Method/UserMethod.php old mode 100644 new mode 100755 index 60e2d378..0b14aac0 --- a/app/Domains/Auth/Models/Traits/Method/UserMethod.php +++ b/app/Domains/Auth/Models/Traits/Method/UserMethod.php @@ -33,6 +33,43 @@ public function isUser(): bool return $this->type === self::TYPE_USER; } + /** + * @return mixed + */ + public function isLecturer(): bool + { + return $this->type === self::TYPE_LECTURER; + } + + /** + * @return mixed + */ + public function isTechOfficer(): bool + { + return $this->type === self::TYPE_TECH_OFFICER; + } + + /** + * @return mixed + */ + public function isMaintainer(): bool + { + return $this->type === self::TYPE_MAINTAINER; + } + + public function isAdminAccess(): bool + { + return ($this->isAdmin() || $this->isLecturer() || $this->isTechOfficer() || $this->isMaintainer()); + } + + /** + * @return mixed + */ + public function hasInventoryAccess(): bool + { + return ($this->isAdmin() || $this->isTechOfficer() || $this->isMaintainer()); + } + /** * @return mixed */ @@ -92,13 +129,13 @@ public function getPermissionDescriptions(): Collection } /** - * @param bool $size + * @param bool $size * * @return mixed|string * @throws \Creativeorange\Gravatar\Exceptions\InvalidEmailException */ public function getAvatar($size = null) { - return 'https://gravatar.com/avatar/'.md5(strtolower(trim($this->email))).'?s='.config('boilerplate.avatar.size', $size).'&d=mp'; + return 'https://gravatar.com/avatar/' . md5(strtolower(trim($this->email))) . '?s=' . config('boilerplate.avatar.size', $size) . '&d=mp'; } } diff --git a/app/Domains/Auth/Models/Traits/Relationship/PermissionRelationship.php b/app/Domains/Auth/Models/Traits/Relationship/PermissionRelationship.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Models/Traits/Relationship/UserRelationship.php b/app/Domains/Auth/Models/Traits/Relationship/UserRelationship.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Models/Traits/Scope/PermissionScope.php b/app/Domains/Auth/Models/Traits/Scope/PermissionScope.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Models/Traits/Scope/RoleScope.php b/app/Domains/Auth/Models/Traits/Scope/RoleScope.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Models/Traits/Scope/UserScope.php b/app/Domains/Auth/Models/Traits/Scope/UserScope.php old mode 100644 new mode 100755 index 4a671cd2..589c804f --- a/app/Domains/Auth/Models/Traits/Scope/UserScope.php +++ b/app/Domains/Auth/Models/Traits/Scope/UserScope.php @@ -83,4 +83,34 @@ public function scopeUsers($query) { return $query->where('type', $this::TYPE_USER); } + + /** + * @param $query + * + * @return mixed + */ + public function scopeLecturers($query) + { + return $query->where('type', $this::TYPE_LECTURER); + } + + /** + * @param $query + * + * @return mixed + */ + public function scopeTechOfficers($query) + { + return $query->where('type', $this::TYPE_TECH_OFFICER); + } + + /** + * @param $query + * + * @return mixed + */ + public function scopeMaintainers($query) + { + return $query->where('type', $this::TYPE_MAINTAINER); + } } diff --git a/app/Domains/Auth/Models/User.php b/app/Domains/Auth/Models/User.php old mode 100644 new mode 100755 index e5a9d65d..8e3ec318 --- a/app/Domains/Auth/Models/User.php +++ b/app/Domains/Auth/Models/User.php @@ -8,6 +8,7 @@ use App\Domains\Auth\Models\Traits\Scope\UserScope; use App\Domains\Auth\Notifications\Frontend\ResetPasswordNotification; use App\Domains\Auth\Notifications\Frontend\VerifyEmail; +use App\Models\Order; use DarkGhostHunter\Laraguard\Contracts\TwoFactorAuthenticatable; use DarkGhostHunter\Laraguard\TwoFactorAuthentication; use Database\Factories\UserFactory; @@ -18,6 +19,7 @@ use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Lab404\Impersonate\Models\Impersonate; +use Laravel\Sanctum\HasApiTokens; use Spatie\Permission\Traits\HasRoles; /** @@ -29,6 +31,7 @@ class User extends Authenticatable implements MustVerifyEmail, TwoFactorAuthenti HasRoles, Impersonate, MustVerifyEmailTrait, + HasApiTokens, Notifiable, SoftDeletes, TwoFactorAuthentication, @@ -39,6 +42,9 @@ class User extends Authenticatable implements MustVerifyEmail, TwoFactorAuthenti public const TYPE_ADMIN = 'admin'; public const TYPE_USER = 'user'; + public const TYPE_LECTURER = 'lecturer'; + public const TYPE_TECH_OFFICER = 'tech_officer'; + public const TYPE_MAINTAINER = 'maintainer'; /** * The attributes that are mass assignable. @@ -157,4 +163,8 @@ protected static function newFactory() { return UserFactory::new(); } + + function orders(){ + return $this->hasMany(Order::class); + } } diff --git a/app/Domains/Auth/Notifications/Frontend/ResetPasswordNotification.php b/app/Domains/Auth/Notifications/Frontend/ResetPasswordNotification.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Notifications/Frontend/VerifyEmail.php b/app/Domains/Auth/Notifications/Frontend/VerifyEmail.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Observers/UserObserver.php b/app/Domains/Auth/Observers/UserObserver.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Rules/UnusedPassword.php b/app/Domains/Auth/Rules/UnusedPassword.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Services/PermissionService.php b/app/Domains/Auth/Services/PermissionService.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Services/RoleService.php b/app/Domains/Auth/Services/RoleService.php old mode 100644 new mode 100755 diff --git a/app/Domains/Auth/Services/UserService.php b/app/Domains/Auth/Services/UserService.php old mode 100644 new mode 100755 diff --git a/app/Exceptions/GeneralException.php b/app/Exceptions/GeneralException.php old mode 100644 new mode 100755 diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php old mode 100644 new mode 100755 diff --git a/app/Exceptions/ReportableException.php b/app/Exceptions/ReportableException.php old mode 100644 new mode 100755 diff --git a/app/Helpers/Global/GeneralHelper.php b/app/Helpers/Global/GeneralHelper.php old mode 100644 new mode 100755 index 839253e7..989e5d05 --- a/app/Helpers/Global/GeneralHelper.php +++ b/app/Helpers/Global/GeneralHelper.php @@ -2,7 +2,7 @@ use Carbon\Carbon; -if (! function_exists('appName')) { +if (!function_exists('appName')) { /** * Helper to grab the application name. * @@ -14,7 +14,7 @@ function appName() } } -if (! function_exists('carbon')) { +if (!function_exists('carbon')) { /** * Create a new Carbon instance from a time. * @@ -29,7 +29,7 @@ function carbon($time) } } -if (! function_exists('homeRoute')) { +if (!function_exists('homeRoute')) { /** * Return the route to the "home" page depending on authentication/authorization status. * @@ -43,7 +43,7 @@ function homeRoute() } if (auth()->user()->isUser()) { - return 'frontend.user.dashboard'; + return 'frontend.user.overview'; } } diff --git a/app/Helpers/Global/HtmlHelper.php b/app/Helpers/Global/HtmlHelper.php old mode 100644 new mode 100755 diff --git a/app/Helpers/Global/LocaleHelper.php b/app/Helpers/Global/LocaleHelper.php old mode 100644 new mode 100755 diff --git a/app/Helpers/Global/SystemHelper.php b/app/Helpers/Global/SystemHelper.php old mode 100644 new mode 100755 diff --git a/app/Helpers/Global/TimezoneHelper.php b/app/Helpers/Global/TimezoneHelper.php old mode 100644 new mode 100755 diff --git a/app/Helpers/Global/_readme.txt b/app/Helpers/Global/_readme.txt old mode 100644 new mode 100755 diff --git a/app/Http/Controllers/Api/Auth/AuthController.php b/app/Http/Controllers/Api/Auth/AuthController.php new file mode 100755 index 00000000..3b931f6f --- /dev/null +++ b/app/Http/Controllers/Api/Auth/AuthController.php @@ -0,0 +1,131 @@ +user(); + } + + + /* + * Create a new user + */ + public function signup(Request $request) + { + $attr = $request->validate([ + 'name' => 'required|string|max:255', + 'email' => 'required|string|email|unique:users,email', + 'password' => 'required|string|min:6|confirmed' + ]); + + $user = User::create([ + 'name' => $attr['name'], + 'password' => bcrypt($attr['password']), + 'email' => $attr['email'] + ]); + + return response()->json([ + 'token' => $user->createToken('tokens')->plainTextToken + ],200); + } + + /* + * Login a new user + **/ + public function login(Request $request) + { + $attr = $request->validate([ + 'email' => 'required|string|email|', + 'password' => 'required|string|min:6' + ]); + + if (!Auth::attempt($attr)) { + return response()->json(['message'=>'Credentials not match'], 401); + } + + return [ + 'token' => auth('api')->user()->createToken('API Token')->plainTextToken + ]; + } + + /* + * signout current user + */ + public function logout() + { + auth('api')->user()->tokens()->delete(); + + return [ + 'message' => 'Tokens Revoked' + ]; + } + + /* + * To send password reset link + */ + public function sendPasswordResetLinkEmail(Request $request) { + $request->validate(['email' => 'required|email']); + + $status = Password::sendResetLink( + $request->only('email') + ); + + if($status === Password::RESET_LINK_SENT) { + return response()->json(['message' => __($status)], 200); + } else { + throw ValidationException::withMessages([ + 'email' => __($status) + ]); + } + } + + + /** + * To reset password + */ + public function resetPassword(Request $request) { + $request->validate([ + 'token' => 'required', + 'email' => 'required|email', + 'password' => 'required|min:8|confirmed', + ]); + + $status = Password::reset( + $request->only('email', 'password', 'password_confirmation', 'token'), + function ($user, $password) use ($request) { + $user->forceFill([ + 'password' => Hash::make($password) + ])->setRememberToken(Str::random(60)); + + $user->save(); + + event(new PasswordReset($user)); + } + ); + + if($status == Password::PASSWORD_RESET) { + return response()->json(['message' => __($status)], 200); + } else { + throw ValidationException::withMessages([ + 'email' => __($status) + ]); + } + } + + +} diff --git a/app/Http/Controllers/Api/Auth/OrderController.php b/app/Http/Controllers/Api/Auth/OrderController.php new file mode 100755 index 00000000..d3bcaf76 --- /dev/null +++ b/app/Http/Controllers/Api/Auth/OrderController.php @@ -0,0 +1,86 @@ +user()->orders()->with('componentItems')->get(); + return response()->json($orders,200); + + } catch (\Exception $ex) { + return response()->json(["message"=>$ex->getMessage()],500); + } + } + + + /** + * Display the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function show($id) + { + $order = auth('api')->user()->orders()->with('componentItems')->find($id); + if ($order==null) + return response()->json(['message'=>'Not found'],404); + else + return response()->json($order,200); + } + + + /** + * set and return the otp for a order. + * + * @return \Illuminate\Http\Response + */ + public function requestOtp($orderId) + { + try { + $order = auth('api')->user()->orders->find($orderId); + if($order!=null){ + $otp = $order->generateOtp(); + return response()->json($otp,200); + } + else{ + return response()->json(['message'=>'Not found'],404); + } + + } catch (\Exception $ex) { + return response()->json(["message"=>$ex->getMessage()],500); + } + } + + /** + * set and return the otp for a order. + * + * @return \Illuminate\Http\Response + */ + public function checkOtp($orderId,$otp) + { + try { + $order = auth('api')->user()->orders->find($orderId); + if($order!=null){ + $res = $order->checkOtp($otp); + return response()->json($res,200); + } + else{ + return response()->json(['message'=>'Not found'],404); + } + + } catch (\Exception $ex) { + return response()->json(["message"=>$ex->getMessage()],500); + } + } +} diff --git a/app/Http/Controllers/Api/ComponentItemController.php b/app/Http/Controllers/Api/ComponentItemController.php new file mode 100755 index 00000000..8dccfc6d --- /dev/null +++ b/app/Http/Controllers/Api/ComponentItemController.php @@ -0,0 +1,223 @@ +json($items, 200); + } catch (\Exception $ex) { + return response()->json([ + "message" => $ex->getMessage() + ], 500); + } + } + + + /** + * Store a newly created resource in storage. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function store(Request $request) + { + $data = request()->validate([ + 'title' => 'string|required', + 'brand' => 'string|nullable', + 'productCode' => 'string|nullable', + 'component_type_id' => 'numeric|required', + + 'specifications' => 'string|nullable', + 'description' => 'string|nullable', + 'instructions' => 'string|nullable', + + 'isAvailable' => 'nullable', + 'isElectrical' => 'nullable', + 'powerRating' => 'numeric|nullable', + 'quantity' => 'numeric|nullable', + 'price' => 'numeric|nullable', + 'size' => 'string|nullable', // [small, medium, large] + + 'thumb' => 'image|nullable|mimes:jpeg,png,jpg,gif,svg|max:2048' + ]); + + try { + if ($request->thumb != null) { + $data['thumb'] = $this->uploadThumb(null, $request->thumb, "component_items"); + } + + $type = new ComponentItem($data); + + // Update checkbox condition + $type->isAvailable = ($request->isAvailable != null); + $type->isElectrical = ($request->isElectrical != null); + + $type->save(); + return response()->json($type, 200); + } catch (\Exception $ex) { + return response()->json([ + "message" => $ex->getMessage() + ], 500); + } + } + + /** + * Display the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function show($id) + { + try { + $item = ComponentItem::find($id); + if ($item != null) { + return response()->json($item, 200); + } else { + return response()->json(["message" => "Item not found!"], 404); + } + } catch (\Exception $ex) { + return response()->json([ + "message" => $ex->getMessage() + ], 500); + } + } + + + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function update(Request $request, $id) + { + $data = request()->validate([ + 'title' => 'string|required', + 'brand' => 'string|nullable', + 'productCode' => 'string|nullable', + 'component_type_id' => 'numeric|required', + + 'specifications' => 'string|nullable', + 'description' => 'string|nullable', + 'instructions' => 'string|nullable', + + 'isAvailable' => 'boolean|nullable', + 'isElectrical' => 'boolean|nullable', + 'powerRating' => 'numeric|nullable', + 'quantity' => 'numeric|nullable', + 'price' => 'numeric|nullable', + 'size' => 'string|nullable', // [small, medium, large] + + 'thumb' => 'image|nullable|mimes:jpeg,png,jpg,gif,svg|max:2048' + ]); + + try { + $componentItem = ComponentItem::find($id); + if ($componentItem == null) { + return response()->json(["message" => "Item not found!"], 404); + } + + if ($request->thumb != null) { + + $data['thumb'] = $this->uploadThumb($componentItem->thumb, $request->thumb, "component_items"); + } + + // Update checkbox condition + $componentItem['isAvailable'] = isset($request->isAvailable) ? 1 : 0; + $componentItem['isElectrical'] = isset($request->isElectrical) ? 1 : 0; + + $componentItem->update($data); + + return response()->json($componentItem, 200); + } catch (\Exception $ex) { + return response()->json([ + "message" => $ex->getMessage() + ], 500); + } + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function destroy($id) + { + try { + $componentItem = ComponentItem::find($id); + if ($componentItem == null) { + return response()->json([ + "message" => "Item is not found" + ], 404); + } + // Delete the thumbnail form the file system + $this->deleteThumb($componentItem->thumb); + + $componentItem->delete(); + return response()->json($componentItem, 200); + } catch (\Exception $ex) { + return response()->json([ + "message" => $ex->getMessage() + ], 500); + } + } + + + private function deleteThumb($currentURL) + { + if ($currentURL != null && $currentURL != config('constants.frontend.dummy_thumb')) { + $oldImage = public_path($currentURL); + if (File::exists($oldImage)) unlink($oldImage); + } + } + + // Private function to handle thumb images + private function uploadThumb($currentURL, $newImage, $folder) + { + // Delete the existing image + $this->deleteThumb($currentURL); + + $imageName = time() . '.' . $newImage->extension(); + $newImage->move(public_path('img/' . $folder), $imageName); + $imagePath = "/img/$folder/" . $imageName; + $image = Image::make(public_path($imagePath))->fit(360, 360); + $image->save(); + + return $imageName; + } + public function search(Request $request) + { + // Get the search value from the request + $term = $request->query('term'); + + // search in the title and body columns from the posts table + $items = ComponentItem::query() + ->where('title', 'LIKE', "%{$term}%") + ->orWhere('description', 'LIKE', "%{$term}%") + ->orWhere('brand', 'LIKE', "%{$term}%") + ->orWhere('specifications', 'LIKE', "%{$term}%") + ->get(); + + // Return the search view with the resluts compacted + return $items; + } +} diff --git a/app/Http/Controllers/Api/ComponentTypeController.php b/app/Http/Controllers/Api/ComponentTypeController.php new file mode 100755 index 00000000..2e535361 --- /dev/null +++ b/app/Http/Controllers/Api/ComponentTypeController.php @@ -0,0 +1,191 @@ +json($types, 200); + } catch (\Exception $ex) { + return response()->json([ + "message" => $ex->getMessage() + ], 500); + } + } + + + + /** + * Store a newly created resource in storage. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function store(Request $request) + { + $data = request()->validate([ + 'title' => 'string|required', + 'parent_id' => 'integer|nullable', // TODO: Validate properly + 'subtitle' => 'string|nullable', + 'description' => 'string|nullable', + 'thumb' => 'image|nullable|mimes:jpeg,jpg,png,jpg,gif,svg|max:2048' + ]); + + try { + if ($request->thumb != null) { + $data['thumb'] = $this->uploadThumb(null, $request->thumb, "component_types"); + } + + $type = new ComponentType($data); + $type->save(); + return response()->json($type, 200); + } catch (\Exception $ex) { + return response()->json([ + "message" => $ex->getMessage() + ], 500); + } + } + + /** + * Display the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function show($id) + { + try { + $type = ComponentType::find($id); + if ($type != null) { + return response()->json($type, 200); + } else { + return response()->json(["message" => "Type is not found!"], 404); + } + } catch (\Exception $ex) { + return response()->json([ + "message" => $ex->getMessage() + ], 500); + } + } + + + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function update(Request $request, $id) + { + $data = request()->validate([ + 'title' => 'string|required', + 'parent_id' => 'integer|nullable', // TODO: Validate properly + 'subtitle' => 'string|nullable', + 'description' => 'string|nullable', + 'thumb' => 'image|nullable|mimes:jpeg,jpg,png,jpg,gif,svg|max:2048' + ]); + + try { + $componentType = ComponentType::find($id); + if ($componentType == null) { + return response()->json(["message" => "Item not found!"], 404); + } + + if ($request->thumb != null) { + $data['thumb'] = $this->uploadThumb($componentType->thumb, $request->thumb, "component_types"); + } + + $componentType->update($data); + return response()->json($componentType, 200); + } catch (\Exception $ex) { + return response()->json([ + "message" => $ex->getMessage() + ], 500); + } + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function destroy($id) + { + try { + $componentType = ComponentType::find($id); + if ($componentType == null) { + return response()->json([ + "message" => "Item is not found" + ], 404); + } + // Delete the thumbnail form the file system + $this->deleteThumb($componentType->thumb); + + $componentType->delete(); + return response()->json($componentType, 200); + } catch (\Exception $ex) { + return response()->json([ + "message" => $ex->getMessage() + ], 500); + } + } + + + private function deleteThumb($currentURL) + { + if ($currentURL != null && $currentURL != config('constants.frontend.dummy_thumb')) { + $oldImage = public_path($currentURL); + if (File::exists($oldImage)) unlink($oldImage); + } + } + + // Private function to handle thumb images + private function uploadThumb($currentURL, $newImage, $folder) + { + // Delete the existing image + $this->deleteThumb($currentURL); + + $imageName = time() . '.' . $newImage->extension(); + $newImage->move(public_path('img/' . $folder), $imageName); + $imagePath = "/img/$folder/" . $imageName; + $image = Image::make(public_path($imagePath))->fit(360, 360); + $image->save(); + + return $imageName; + } + + public function search(Request $request) + { + // Get the search value from the request + $term = $request->query('term'); + + // search in the title and body columns from the posts table + $types = ComponentType::query() + ->where('title', 'LIKE', "%{$term}%") + ->orWhere('subtitle', 'LIKE', "%{$term}%") + ->orWhere('description', 'LIKE', "%{$term}%") + ->get(); + + // Return the search view with the resluts compacted + return $types; + } +} diff --git a/app/Http/Controllers/Api/EquipmentItemController.php b/app/Http/Controllers/Api/EquipmentItemController.php new file mode 100755 index 00000000..0efa5043 --- /dev/null +++ b/app/Http/Controllers/Api/EquipmentItemController.php @@ -0,0 +1,229 @@ +json($items, 200); + } catch (\Exception $ex) { + return response()->json([ + "message" => $ex->getMessage() + ], 500); + } + } + + + + /** + * Store a newly created resource in storage. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\JsonResponse + */ + public function store(Request $request) + { + $data = request()->validate([ + 'title' => 'string|required', + 'brand' => 'string|nullable', + 'productCode' => 'string|nullable', + 'equipment_type_id' => 'numeric|required', + + 'specifications' => 'string|nullable', + 'description' => 'string|nullable', + 'instructions' => 'string|nullable', + + // 'isElectrical' => 'accepted', + 'powerRating' => 'numeric|nullable', + 'price' => 'numeric|nullable', + 'quantity' => 'numeric', + + 'width' => 'numeric|nullable', + 'length' => 'numeric|nullable', + 'height' => 'numeric|nullable', + 'weight' => 'numeric|nullable', + + 'thumb' => 'image|nullable|mimes:jpeg,jpg,png,jpg,gif,svg|max:2048' + ]); + + try { + if ($request->thumb != null) { + $data['thumb'] = $this->uploadThumb(null, $request->thumb, "equipment_items"); + } + + $item = new EquipmentItem($data); + + // Update checkbox condition + $item->isElectrical = ($request->isElectrical != null); + + $item->save(); + return response()->json($item, 200); + } catch (\Exception $ex) { + return response()->json([ + "message" => $ex->getMessage() + ], 500); + } + } + + /** + * Display the specified resource. + * + * @param int $id + * @return \Illuminate\Http\JsonResponse + */ + public function show($id) + { + try { + $item = EquipmentItem::find($id); + if ($item != null) { + return response()->json($item, 200); + } else { + return response()->json(["message" => "Item is not found!"], 404); + } + } catch (\Exception $ex) { + return response()->json([ + "message" => $ex->getMessage() + ], 500); + } + } + + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\JsonResponse + */ + public function update(Request $request, $id) + { + $data = request()->validate([ + 'title' => 'string|required', + 'brand' => 'string|nullable', + 'productCode' => 'string|nullable', + 'equipment_type_id' => 'numeric|required', + + 'specifications' => 'string|nullable', + 'description' => 'string|nullable', + 'instructions' => 'string|nullable', + + 'isElectrical' => 'nullable', + 'powerRating' => 'numeric|nullable', + 'price' => 'numeric|nullable', + 'quantity' => 'numeric', + + 'width' => 'numeric|nullable', + 'length' => 'numeric|nullable', + 'height' => 'numeric|nullable', + 'weight' => 'numeric|nullable', + + 'thumb' => 'image|nullable|mimes:jpeg,png,jpg,gif,svg|max:2048' + ]); + + try { + $equipmentItem = EquipmentItem::find($id); + if ($equipmentItem == null) { + return response()->json(["message" => "Item not found!"], 404); + } + + if ($request->thumb != null) { + $data['thumb'] = $this->uploadThumb($equipmentItem->thumb, $request->thumb, "equipment_items"); + } + + // Update checkbox condition + $equipmentItem->isElectrical = ($request->isElectrical != null); + + $equipmentItem->update($data); + return response()->json($equipmentItem, 200); + } catch (\Exception $ex) { + return response()->json([ + "message" => $ex->getMessage() + ], 500); + } + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * @return \Illuminate\Http\JsonResponse + */ + public function destroy($id) + { + try { + $equipmentItem = EquipmentItem::find($id); + if ($equipmentItem == null) { + return response()->json([ + "message" => "Item is not found" + ], 404); + } + // Delete the thumbnail form the file system + $this->deleteThumb($equipmentItem->thumb); + + $equipmentItem->delete(); + return response()->json($equipmentItem, 200); + } catch (\Exception $ex) { + return response()->json([ + "message" => $ex->getMessage() + ], 500); + } + } + + + + private function deleteThumb($currentURL) + { + if ($currentURL != null && $currentURL != config('constants.frontend.dummy_thumb')) { + $oldImage = public_path($currentURL); + if (File::exists($oldImage)) unlink($oldImage); + } + } + + // Private function to handle thumb images + private function uploadThumb($currentURL, $newImage, $folder) + { + // Delete the existing image + $this->deleteThumb($currentURL); + + $imageName = time() . '.' . $newImage->extension(); + $newImage->move(public_path('img/' . $folder), $imageName); + $imagePath = "/img/$folder/" . $imageName; + $image = Image::make(public_path($imagePath))->fit(360, 360); + $image->save(); + + return $imageName; + } + + public function search(Request $request) + { + // Get the search value from the request + $term = $request->query('term'); + + // search in the title and body columns from the posts table + $items = EquipmentItem::query() + ->where('title', 'LIKE', "%{$term}%") + ->orWhere('description', 'LIKE', "%{$term}%") + ->orWhere('brand', 'LIKE', "%{$term}%") + ->orWhere('specifications', 'LIKE', "%{$term}%") + ->orWhere('instructions', 'LIKE', "%{$term}%") + ->get(); + + // Return the search view with the resluts compacted + return $items; + } +} diff --git a/app/Http/Controllers/Api/EquipmentTypeController.php b/app/Http/Controllers/Api/EquipmentTypeController.php new file mode 100755 index 00000000..f341a3ae --- /dev/null +++ b/app/Http/Controllers/Api/EquipmentTypeController.php @@ -0,0 +1,191 @@ +json($types, 200); + } catch (\Exception $ex) { + return response()->json([ + "message" => $ex->getMessage() + ], 500); + } + } + + + + /** + * Store a newly created resource in storage. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function store(Request $request) + { + $data = request()->validate([ + 'title' => 'string|required', + 'parent_id' => 'integer|nullable', // TODO: Validate properly + 'subtitle' => 'string|nullable', + 'description' => 'string|nullable', + 'thumb' => 'image|nullable|mimes:jpeg,jpg,png,jpg,gif,svg|max:2048' + ]); + + try { + if ($request->thumb != null) { + $data['thumb'] = $this->uploadThumb(null, $request->thumb, "equipment_types"); + } + + $type = new EquipmentType($data); + $type->save(); + return response()->json($type, 200); + } catch (\Exception $ex) { + return response()->json([ + "message" => $ex->getMessage() + ], 500); + } + } + + /** + * Display the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function show($id) + { + try { + $type = EquipmentType::find($id); + if ($type != null) { + return response()->json($type, 200); + } else { + return response()->json(["message" => "Type is not found!"], 404); + } + } catch (\Exception $ex) { + return response()->json([ + "message" => $ex->getMessage() + ], 500); + } + } + + + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function update(Request $request, $id) + { + $data = request()->validate([ + 'title' => 'string|required', + 'parent_id' => 'integer|nullable', // TODO: Validate properly + 'subtitle' => 'string|nullable', + 'description' => 'string|nullable', + 'thumb' => 'image|nullable|mimes:jpeg,jpg,png,jpg,gif,svg|max:2048' + ]); + + try { + + + $equipmentType = EquipmentType::find($id); + if ($equipmentType == null) { + return response()->json(["message" => "Item not found!"], 404); + } + if ($request->thumb != null) { + $data['thumb'] = $this->uploadThumb($equipmentType->thumb, $request->thumb, "equipment_items"); + } + + + $equipmentType->update($data); + return response()->json($equipmentType, 200); + } catch (\Exception $ex) { + return response()->json([ + "message" => $ex->getMessage() + ], 500); + } + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function destroy($id) + { + try { + $equipmentType = EquipmentType::find($id); + if ($equipmentType == null) { + return response()->json([ + "message" => "Type is not found" + ], 404); + } + // Delete the thumbnail form the file system + $this->deleteThumb($equipmentType->thumb); + + $equipmentType->delete(); + return response()->json($equipmentType, 200); + } catch (\Exception $ex) { + return response()->json([ + "message" => $ex->getMessage() + ], 500); + } + } + + private function deleteThumb($currentURL) + { + if ($currentURL != null && $currentURL != config('constants.frontend.dummy_thumb')) { + $oldImage = public_path($currentURL); + if (File::exists($oldImage)) unlink($oldImage); + } + } + + // Private function to handle thumb images + private function uploadThumb($currentURL, $newImage, $folder) + { + // Delete the existing image + $this->deleteThumb($currentURL); + + $imageName = time() . '.' . $newImage->extension(); + $newImage->move(public_path('img/' . $folder), $imageName); + $imagePath = "/img/$folder/" . $imageName; + $image = Image::make(public_path($imagePath))->fit(360, 360); + $image->save(); + + return $imageName; + } + + public function search(Request $request) + { + // Get the search value from the request + $term = $request->query('term'); + + // search in the title and body columns from the posts table + $types = EquipmentType::query() + ->where('title', 'LIKE', "%{$term}%") + ->orWhere('subtitle', 'LIKE', "%{$term}%") + ->orWhere('description', 'LIKE', "%{$term}%") + ->get(); + + // Return the search view with the resluts compacted + return $types; + } +} diff --git a/app/Http/Controllers/Api/OrderController.php b/app/Http/Controllers/Api/OrderController.php new file mode 100755 index 00000000..d79be1bf --- /dev/null +++ b/app/Http/Controllers/Api/OrderController.php @@ -0,0 +1,146 @@ +get(); + try { + return response()->json($orders,200); + } catch (\Exception $ex) { + return response()->json([ + "message"=>$ex->getMessage() + ],500); + } + } + + + /** + * Store a newly created resource in storage. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function store(Request $request) + { + $data = request()->validate([ + + 'picked_date' => 'string|nullable', // TODO: Validate properly + 'due_date_to_return' => 'string|required', + 'returned_date' => 'string|nullable', + 'status' => 'string|required', + ]); + try { + $data['ordered_date'] = Carbon::now()->format('Y-m-d'); + $data['user_id'] = $request->user()->id; + $order = new Order($data); + $order->save(); + return response()->json($order,200); + + } catch (\Exception $ex) { + return response()->json([ + "message"=>$ex->getMessage() + ],500); + } + } + + /** + * Display the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function show($id) + { + try + { + $order = Order::with('componentItems')->find($id); + if($order!=null) + { + return response()->json($order,200); + } + else + { + return response()->json(["message"=>"Order is not found!"],404); + } + } + catch (\Exception $ex) { + return response()->json([ + "message"=>$ex->getMessage() + ],500); + } + } + + + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function update(Request $request, $id) + { + $data = request()->validate([ + 'ordered_date' => 'string|required', + 'picked_date' => 'string|nullable', // TODO: Validate properly + 'due_date_to_return' => 'string|required', + 'returned_date' => 'string|nullable', + 'status' => 'string|required', + ]); + + try { + $order = Order::find($id); + if($order ==null){ + return response()->json(["message"=>"Order is not found!"],404); + } + $order->update($data); + return response()->json($order,200); + + } catch (\Exception $ex) { + return response()->json([ + "message"=>$ex->getMessage() + ],500); + } + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function destroy($id) + { + try { + $order = Order::find($id); + if($order==null){ + return response()->json([ + "message"=>"Type is not found" + ],404); + } + + $order->delete(); + return response()->json($order,200); + + } catch (\Exception $ex) { + return response()->json([ + "message"=>$ex->getMessage() + ],500); + } + } +} diff --git a/app/Http/Controllers/Api/SearchController.php b/app/Http/Controllers/Api/SearchController.php new file mode 100755 index 00000000..69e3a9b7 --- /dev/null +++ b/app/Http/Controllers/Api/SearchController.php @@ -0,0 +1,38 @@ +search($request); + $ctypes = (new ComponentTypeController)->search($request); + $eitems = (new EquipmentItemController)->search($request); + $etypes = (new EquipmentTypeController)->search($request); + + // search in the title and body columns from the posts table + $result = array_merge(["Component Items"=>$citems], + ["Component Types"=>$ctypes], + ["Equipment Items"=>$eitems], + ["Equipment Types"=>$etypes]); + + // Return the search view with the resluts compacted + return $result; + } + +} diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php old mode 100644 new mode 100755 diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php old mode 100644 new mode 100755 diff --git a/app/Http/Controllers/Auth/VerificationController.php b/app/Http/Controllers/Auth/VerificationController.php old mode 100644 new mode 100755 diff --git a/app/Http/Controllers/Backend/AnnouncementController.php b/app/Http/Controllers/Backend/AnnouncementController.php new file mode 100755 index 00000000..b179503c --- /dev/null +++ b/app/Http/Controllers/Backend/AnnouncementController.php @@ -0,0 +1,120 @@ +validate([ + 'area' => ['required', Rule::in(array_keys(Announcement::areas()))], + 'type' => ['required', Rule::in(array_keys(Announcement::types()))], + 'message' => 'string|required', + 'enabled' => 'nullable', + 'starts_at' => 'required|date_format:Y-m-d\\TH:i', + 'ends_at' => 'required|date_format:Y-m-d\\TH:i', // TODO: Test ends>starts + ]); + + try { + $announcement = new Announcement($data); + $announcement->enabled = ($request->enabled != null); + $announcement->save(); + + return redirect()->route('admin.announcements.index', $announcement)->with('Success', 'Announcement was created !'); + } catch (\Exception $ex) { + return abort(500); + } + } + + /** + * Show the form for editing the specified resource. + * + * @param \App\Models\Announcement $announcement + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + */ + public function edit(Announcement $announcement) + { + $areas = Announcement::areas(); + $types = Announcement::types(); + return view('backend.announcements.edit', compact('announcement', 'areas', 'types')); + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param \App\Models\Announcement $announcement + * @return \Illuminate\Http\RedirectResponse + */ + public function update(Request $request, Announcement $announcement) + { + $data = request()->validate([ + 'area' => ['required', Rule::in(array_keys(Announcement::areas()))], + 'type' => ['required', Rule::in(array_keys(Announcement::types()))], + 'message' => 'string|required', + 'enabled' => 'nullable', + 'starts_at' => 'required|date_format:Y-m-d\\TH:i', + 'ends_at' => 'required|date_format:Y-m-d\\TH:i', // TODO: Test ends>starts + ]); + + try { + $announcement->enabled = ($request->enabled != null); + $announcement->update($data); + return redirect()->route('admin.announcements.index')->with('Success', 'Announcement was updated !'); + } catch (\Exception $ex) { + return abort(500); + } + } + + /** + * Confirm to delete the specified resource from storage. + * + * @param \App\Models\Announcement $announcement + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + */ + public function delete(Announcement $announcement) + { + return view('backend.announcements.delete', compact('announcement')); + } + + + /** + * Remove the specified resource from storage. + * + * @param \App\Models\Announcement $announcement + * @return \Illuminate\Http\RedirectResponse|null + */ + public function destroy(Announcement $announcement) + { + try { + $announcement->delete(); + return redirect()->route('admin.announcements.index')->with('Success', 'Annuncement was deleted !'); + } catch (\Exception $ex) { + return abort(500); + } + } +} diff --git a/app/Http/Controllers/Backend/ComponentItemController.php b/app/Http/Controllers/Backend/ComponentItemController.php old mode 100644 new mode 100755 index bed0fcbb..cffe1bc9 --- a/app/Http/Controllers/Backend/ComponentItemController.php +++ b/app/Http/Controllers/Backend/ComponentItemController.php @@ -5,10 +5,13 @@ use App\Http\Controllers\Controller; use App\Models\ComponentItem; use App\Models\ComponentType; +use App\Models\ItemLocations; +use App\Models\Locations; use Illuminate\Http\Request; use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\Storage; use Intervention\Image\Facades\Image; +use Torann\GeoIP\Location; class ComponentItemController extends Controller { @@ -20,8 +23,8 @@ class ComponentItemController extends Controller public function index() { - $components = ComponentItem::paginate(12); - return view("backend.component.items.index", compact('components')); + //$components = ComponentItem::paginate(16); + return view("backend.component.items.index"); } /** @@ -31,8 +34,9 @@ public function index() */ public function create() { - $types = ComponentType::pluck('title', 'id'); - return view('backend.component.items.create', compact('types')); + $types = ComponentType::getFullTypeList(); + $locations = Locations::pluck('location', 'id'); + return view('backend.component.items.create', compact('types', 'locations')); } /** @@ -51,14 +55,10 @@ public function store(Request $request) 'specifications' => 'string|nullable', 'description' => 'string|nullable', - 'instructions' => 'string|nullable', + 'datasheet' => 'url|nullable', - 'isAvailable' => 'nullable', - 'isElectrical' => 'nullable', - 'powerRating' => 'numeric|nullable', 'quantity' => 'numeric|nullable', 'price' => 'numeric|nullable', - 'size' => 'string|nullable', // [small, medium, large] 'thumb' => 'image|nullable|mimes:jpeg,png,jpg,gif,svg|max:2048' ]); @@ -69,14 +69,9 @@ public function store(Request $request) } $type = new ComponentItem($data); - - // Update checkbox condition - $type->isAvailable = ($request->isAvailable != null); - $type->isElectrical = ($request->isElectrical != null); - $type->save(); - return redirect()->route('admin.component.items.index')->with('Success', 'component was created !'); + return redirect()->route('admin.component.items.index', $type)->with('Success', 'Component was created !'); } catch (\Exception $ex) { return abort(500); } @@ -90,7 +85,13 @@ public function store(Request $request) */ public function show(ComponentItem $componentItem) { - return view('backend.component.items.show', compact("componentItem")); + $locationCount = $this->getNumberOfLocationsForItem($componentItem); + + $locations_array = array(); + for ($i = 0; $i < $locationCount; $i++) { + $locations_array[] = $this->getFullLocationPathAsString($componentItem, $i); + } + return view('backend.component.items.show', compact("componentItem", 'locations_array')); } /** @@ -101,10 +102,17 @@ public function show(ComponentItem $componentItem) */ public function edit(ComponentItem $componentItem) { - $types = ComponentType::pluck('title', 'id'); + $types = ComponentType::getFullTypeList(); return view('backend.component.items.edit', compact('types', 'componentItem')); } + public function editLocation(ComponentItem $componentItem) + { + $locations = Locations::all()->where('parent_location', 1)->all(); + + return view('backend.component.items.edit-location', compact('componentItem', 'locations')); + } + /** * Update the specified resource in storage. * @@ -122,31 +130,22 @@ public function update(Request $request, ComponentItem $componentItem) 'specifications' => 'string|nullable', 'description' => 'string|nullable', - 'instructions' => 'string|nullable', + 'datasheet' => 'url|nullable', - 'isAvailable' => 'boolean|nullable', - 'isElectrical' => 'boolean|nullable', - 'powerRating' => 'numeric|nullable', 'quantity' => 'numeric|nullable', 'price' => 'numeric|nullable', - 'size' => 'string|nullable', // [small, medium, large] 'thumb' => 'image|nullable|mimes:jpeg,png,jpg,gif,svg|max:2048' ]); try { if ($request->thumb != null) { - $data['thumb'] = $this->uploadThumb($componentItem->thumbURL(), $request->thumb, "component_items"); + $data['thumb'] = $this->uploadThumb($componentItem->thumb, $request->thumb, "component_items"); } - // Update checkbox condition - $componentItem['isAvailable'] = isset($request->isAvailable) ? 1 : 0; - $componentItem['isElectrical'] = isset($request->isElectrical) ? 1 : 0; - $componentItem->update($data); return redirect()->route('admin.component.items.index')->with('Success', 'Component was updated !'); - } catch (\Exception $ex) { return abort(500); } @@ -174,11 +173,17 @@ public function destroy(ComponentItem $componentItem) { try { // Delete the thumbnail form the file system - $this->deleteThumb($componentItem->thumbURL()); + $this->deleteThumb($componentItem->thumb); $componentItem->delete(); - return redirect()->route('admin.component.items.index')->with('Success', 'Component was deleted !'); + // delete location entries + $this_item_locations = ItemLocations::where('item_id', $componentItem->inventoryCode())->get(); + foreach ($this_item_locations as $loc) { + $loc->delete(); + } + + return redirect()->route('admin.component.items.index')->with('Success', 'Component was deleted !'); } catch (\Exception $ex) { return abort(500); } @@ -186,7 +191,7 @@ public function destroy(ComponentItem $componentItem) private function deleteThumb($currentURL) { - if ($currentURL != null) { + if ($currentURL != null && $currentURL != config('constants.frontend.dummy_thumb')) { $oldImage = public_path($currentURL); if (File::exists($oldImage)) unlink($oldImage); } diff --git a/app/Http/Controllers/Backend/ComponentTypeController.php b/app/Http/Controllers/Backend/ComponentTypeController.php old mode 100644 new mode 100755 index a1917366..40d75b4b --- a/app/Http/Controllers/Backend/ComponentTypeController.php +++ b/app/Http/Controllers/Backend/ComponentTypeController.php @@ -19,8 +19,8 @@ class ComponentTypeController extends Controller */ public function index() { - $componentTypes = ComponentType::paginate(12); - return view('backend.component.types.index', compact('componentTypes')); + //$componentTypes = ComponentType::paginate(16); + return view('backend.component.types.index'); } /** @@ -30,7 +30,7 @@ public function index() */ public function create() { - $types = ComponentType::pluck('title', 'id'); + $types = ComponentType::getFullTypeList(); return view('backend.component.types.create', compact('types')); } @@ -58,7 +58,6 @@ public function store(Request $request) $type = new ComponentType($data); $type->save(); return redirect()->route('admin.component.types.index')->with('Success', 'ComponentType was created !'); - } catch (\Exception $ex) { dd($ex); return abort(500, "Error 222"); @@ -84,7 +83,7 @@ public function show(ComponentType $componentType) */ public function edit(ComponentType $componentType) { - $types = ComponentType::pluck('title', 'id'); + $types = ComponentType::getFullTypeList(); return view('backend.component.types.edit', compact('componentType', 'types')); } @@ -107,12 +106,11 @@ public function update(Request $request, ComponentType $componentType) try { if ($request->thumb != null) { - $data['thumb'] = $this->uploadThumb($componentType->thumbURL(), $request->thumb, "component_types"); + $data['thumb'] = $this->uploadThumb($componentType->thumb, $request->thumb, "component_types"); } $componentType->update($data); return redirect()->route('admin.component.types.index')->with('Success', 'ComponentType was updated !'); - } catch (\Exception $ex) { return abort(500); } @@ -133,17 +131,16 @@ public function delete(ComponentType $componentType) /** * Remove the specified resource from storage. * - * @param \App\Models\CompoenentType $componentType + * @param \App\Models\CompoenentType $componentType * @return \Illuminate\Http\RedirectResponse|void */ public function destroy(ComponentType $componentType) { try { // Delete the thumbnail form the file system - $this->deleteThumb($componentType->thumbUrl()); + $this->deleteThumb($componentType->thumb); $componentType->delete(); return redirect()->route('admin.component.types.index')->with('Success', 'ComponentType was deleted !'); - } catch (\Exception $ex) { return abort(500); } @@ -157,7 +154,7 @@ public function destroy(ComponentType $componentType) */ private function deleteThumb($currentURL) { - if ($currentURL != null) { + if ($currentURL != null && $currentURL != config('constants.frontend.dummy_thumb')) { $oldImage = public_path($currentURL); if (File::exists($oldImage)) unlink($oldImage); } diff --git a/app/Http/Controllers/Backend/ConsumableItemController.php b/app/Http/Controllers/Backend/ConsumableItemController.php new file mode 100755 index 00000000..33ccc77f --- /dev/null +++ b/app/Http/Controllers/Backend/ConsumableItemController.php @@ -0,0 +1,215 @@ +validate([ + 'title' => 'string|required', + 'char' => 'string|nullable', + 'consumable_type_id' => 'numeric|required', + 'specifications' => 'string|nullable', + 'formFactor' => 'nullable', + 'datasheetURL' => 'nullable', + 'quantity' => 'numeric|nullable', + 'price' => 'numeric|nullable', + 'thumb' => 'image|nullable|mimes:jpeg,png,jpg,gif,svg|max:2048' + ]); + + // try { + if ($request->thumb != null) { + $data['thumb'] = $this->uploadThumb(null, $request->thumb, "consumable_items"); + } + + $consumableItem = new ConsumableItem($data); + $consumableItem->save(); + + return redirect()->route('admin.consumable.items.edit.location', $consumableItem)->with('Success', 'Consumable was created !'); + // } catch (\Exception $ex) { + // return abort(500); + // } + } + + /** + * Display the specified resource. + * + * @param ConsumableItem $consumableItem + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + */ + public function show(ConsumableItem $consumableItem) + { + $locationCount = $this->getNumberOfLocationsForItem($consumableItem); + + $locations_array = array(); + for ($i = 0; $i < $locationCount; $i++) { + $locations_array[] = $this->getFullLocationPathAsString($consumableItem, $i); + } + return view('backend.consumable.items.show', compact("consumableItem", 'locations_array')); + } + + /** + * Show the form for editing the specified resource. + * + * @param ConsumableItem $consumableItem + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + */ + public function edit(ConsumableItem $consumableItem) + { + $types = ConsumableType::getFullTypeList(); + $locations = Locations::pluck('location', 'id'); + return view('backend.consumable.items.edit', compact('types', 'consumableItem', 'locations')); + } + + /** + * Edit the locations ot the item + * + * @param EquipmentItem $equipmentItem + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + */ + public function editLocation(ConsumableItem $consumableItem) + { + $locations = Locations::all()->where('parent_location', 1)->all(); + + return view('backend.consumable.items.edit-location', compact('consumableItem', 'locations')); + } + + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param ConsumableItem $consumableItem + * @return \Illuminate\Http\RedirectResponse + */ + public function update(Request $request, ConsumableItem $consumableItem) + { + $data = request()->validate([ + 'title' => 'string|required', + 'char' => 'string|nullable', + 'consumable_type_id' => 'numeric|required', + 'specifications' => 'string|nullable', + 'formFactor' => 'nullable', + 'datasheetURL' => 'nullable', + 'quantity' => 'numeric|nullable', + 'price' => 'numeric|nullable', + 'thumb' => 'image|nullable|mimes:jpeg,png,jpg,gif,svg|max:2048' + ]); + + try { + if ($request->thumb != null) { + $data['thumb'] = $this->uploadThumb($consumableItem->thumb, $request->thumb, "consumable_items"); + } + + $filtered_data = $data; + unset($filtered_data['location']); + $consumableItem->update($filtered_data); + + return redirect()->route('admin.consumable.items.index')->with('Success', 'Consumable was updated !'); + } catch (\Exception $ex) { + return abort(500); + } + } + + /** + * Confirm to delete the specified resource from storage. + * + * @param ConsumableItem $consumableItem + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + */ + public function delete(ConsumableItem $consumableItem) + { + return view('backend.consumable.items.delete', compact('consumableItem')); + } + + + /** + * Remove the specified resource from storage. + * + * @param ConsumableItem $consumableItem + * @return \Illuminate\Http\RedirectResponse|null + */ + public function destroy(ConsumableItem $consumableItem) + { + try { + // Delete the thumbnail form the file system + $this->deleteThumb($consumableItem->thumb); + + $consumableItem->delete(); + + // Delete location entries + $this_item_locations = ItemLocations::where('item_id', $consumableItem->inventoryCode())->get(); + foreach ($this_item_locations as $loc) { + $loc->delete(); + } + return redirect()->route('admin.consumable.items.index')->with('Success', 'Consumable was deleted !'); + } catch (\Exception $ex) { + return abort(500); + } + } + + private function deleteThumb($currentURL) + { + if ($currentURL != null && $currentURL != config('constants.frontend.dummy_thumb')) { + $oldImage = public_path($currentURL); + if (File::exists($oldImage)) unlink($oldImage); + } + } + + // Private function to handle thumb images + private function uploadThumb($currentURL, $newImage, $folder) + { + // Delete the existing image + $this->deleteThumb($currentURL); + + $imageName = time() . '.' . $newImage->extension(); + $newImage->move(public_path('img/' . $folder), $imageName); + $imagePath = "/img/$folder/" . $imageName; + $image = Image::make(public_path($imagePath))->fit(360, 360); + $image->save(); + + return $imageName; + } +} diff --git a/app/Http/Controllers/Backend/ConsumableTypeController.php b/app/Http/Controllers/Backend/ConsumableTypeController.php new file mode 100755 index 00000000..575619eb --- /dev/null +++ b/app/Http/Controllers/Backend/ConsumableTypeController.php @@ -0,0 +1,169 @@ +validate([ + 'title' => 'string|required', + 'parent_id' => 'integer|nullable', // TODO: Validate properly + 'subtitle' => 'string|nullable', + 'description' => 'string|nullable', + 'thumb' => 'image|nullable|mimes:jpeg,jpg,png,jpg,gif,svg|max:2048' + ]); + + try { + if ($request->thumb != null) { + $data['thumb'] = $this->uploadThumb(null, $request->thumb, "consumable_types"); + } + + $type = new ConsumableType($data); + $type->save(); + + return redirect()->route('admin.consumable.types.index')->with('Success', 'ConsumableType was created !'); + } catch (\Exception $ex) { + return abort(500, "Error 222"); + } + } + + /** + * Display the specified resource. + * + * @param ConsumableType $consumableType + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\Response + */ + public function show(ConsumableType $consumableType) + { + return view('backend.consumable.types.show', compact('consumableType')); + } + + /** + * Show the form for editing the specified resource. + * + * @param int $id + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\Response + */ + public function edit(ConsumableType $consumableType) + { + $types = ConsumableType::getFullTypeList(); + return view('backend.consumable.types.edit', compact('consumableType', 'types')); + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\RedirectResponse|void + */ + public function update(Request $request, ConsumableType $consumableType) + { + $data = request()->validate([ + 'title' => 'string|required', + 'parent_id' => 'integer|nullable', // TODO: Validate properly + 'subtitle' => 'string|nullable', + 'description' => 'string|nullable', + 'thumb' => 'image|nullable|mimes:jpeg,jpg,png,jpg,gif,svg|max:2048' + ]); + + try { + if ($request->thumb != null) { + $data['thumb'] = $this->uploadThumb($consumableType->thumb, $request->thumb, "consumable_types"); + } + + $consumableType->update($data); + return redirect()->route('admin.consumable.types.index')->with('Success', 'ConsumableType was updated !'); + } catch (\Exception $ex) { + return abort(500); + } + } + + /** + * Confirm to delete the specified resource from storage. + * + * @param ConsumableType $consumableType + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + */ + public function delete(ConsumableType $consumableType) + { + return view('backend.consumable.types.delete', compact('consumableType')); + } + + /** + * Remove the specified resource from storage. + * + * @param ConsumableType $consumableType + * @return \Illuminate\Http\RedirectResponse|void + */ + public function destroy(ConsumableType $consumableType) + { + try { + // Delete the thumbnail form the file system + $this->deleteThumb($consumableType->thumb); + + $consumableType->delete(); + return redirect()->route('admin.consumable.types.index')->with('Success', 'ConsumableType was deleted !'); + } catch (\Exception $ex) { + return abort(500); + } + } + + private function deleteThumb($currentURL) + { + if ($currentURL != null && $currentURL != config('constants.frontend.dummy_thumb')) { + $oldImage = public_path($currentURL); + if (File::exists($oldImage)) unlink($oldImage); + } + } + + // Private function to handle thumb images + private function uploadThumb($currentURL, $newImage, $folder): string + { + + // Delete the existing image + $this->deleteThumb($currentURL); + + $imageName = time() . '.' . $newImage->extension(); + $newImage->move(public_path('img/' . $folder), $imageName); + $imagePath = "/img/$folder/" . $imageName; + $image = Image::make(public_path($imagePath))->fit(360, 360); + $image->save(); + + return $imageName; + } +} diff --git a/app/Http/Controllers/Backend/DashboardController.php b/app/Http/Controllers/Backend/DashboardController.php old mode 100644 new mode 100755 index e90ae935..a34f09b9 --- a/app/Http/Controllers/Backend/DashboardController.php +++ b/app/Http/Controllers/Backend/DashboardController.php @@ -5,8 +5,13 @@ use App\Domains\Auth\Models\User; use App\Models\ComponentItem; use App\Models\ComponentType; +use App\Models\ConsumableItem; +use App\Models\ConsumableType; use App\Models\EquipmentItem; use App\Models\EquipmentType; +use App\Models\Stations; + +use function PHPUnit\Framework\countOf; /** * Class DashboardController. @@ -23,7 +28,12 @@ public function index() $equipmentTypeCount = EquipmentType::all()->count(); $componentCount = ComponentItem::all()->count(); $componentTypeCount = ComponentType::all()->count(); + $consumableCount = ConsumableItem::all()->count(); + $consumableTypeCount = ConsumableType::all()->count(); + $stationCount = Stations::all()->count(); + $consumableCount = ConsumableItem::all()->count(); + $consumableTypeCount = ConsumableType::all()->count(); - return view('backend.dashboard', compact('userCount', 'equipmentCount', 'equipmentTypeCount', 'componentCount', 'componentTypeCount')); + return view('backend.dashboard', compact('userCount', 'equipmentCount', 'equipmentTypeCount', 'componentCount', 'componentTypeCount', 'consumableCount', 'consumableTypeCount', 'stationCount')); } } diff --git a/app/Http/Controllers/Backend/EquipmentItemController.php b/app/Http/Controllers/Backend/EquipmentItemController.php old mode 100644 new mode 100755 index e4b05c8c..85d6ce29 --- a/app/Http/Controllers/Backend/EquipmentItemController.php +++ b/app/Http/Controllers/Backend/EquipmentItemController.php @@ -5,9 +5,10 @@ use App\Http\Controllers\Controller; use App\Models\EquipmentItem; use App\Models\EquipmentType; +use App\Models\ItemLocations; +use App\Models\Locations; use Illuminate\Http\Request; use Illuminate\Support\Facades\File; -use Illuminate\Support\Facades\Storage; use Intervention\Image\Facades\Image; class EquipmentItemController extends Controller @@ -19,7 +20,7 @@ class EquipmentItemController extends Controller */ public function index() { - $equipment = EquipmentItem::orderBy('id', 'desc')->paginate(16); + $equipment = EquipmentItem::orderBy('id', 'asc')->paginate(16); return view('backend.equipment.items.index', compact('equipment')); } @@ -30,8 +31,9 @@ public function index() */ public function create() { - $types = EquipmentType::pluck('title', 'id'); - return view('backend.equipment.items.create', compact('types')); + $types = EquipmentType::getFullTypeList(); + $locations = Locations::pluck('location', 'id'); + return view('backend.equipment.items.create', compact('types', 'locations')); } /** @@ -47,7 +49,6 @@ public function store(Request $request) 'brand' => 'string|nullable', 'productCode' => 'string|nullable', 'equipment_type_id' => 'numeric|required', - 'specifications' => 'string|nullable', 'description' => 'string|nullable', 'instructions' => 'string|nullable', @@ -75,9 +76,9 @@ public function store(Request $request) // Update checkbox condition $type->isElectrical = ($request->isElectrical != null); + // save first, otherwise the id is not there $type->save(); - return redirect()->route('admin.equipment.items.index')->with('Success', 'Equipment was created !'); - + return redirect()->route('backend.equipment.items.index', $type)->with('Success', 'Equipment was created !'); } catch (\Exception $ex) { return abort(500); } @@ -91,7 +92,13 @@ public function store(Request $request) */ public function show(EquipmentItem $equipmentItem) { - return view('backend.equipment.items.show', compact('equipmentItem')); + $locationCount = $this->getNumberOfLocationsForItem($equipmentItem); + + $locations_array = array(); + for ($i = 0; $i < $locationCount; $i++) { + $locations_array[] = $this->getFullLocationPathAsString($equipmentItem, $i); + } + return view('backend.equipment.items.show', compact('equipmentItem', 'locations_array')); } /** @@ -102,10 +109,32 @@ public function show(EquipmentItem $equipmentItem) */ public function edit(EquipmentItem $equipmentItem) { - $types = EquipmentType::pluck('title', 'id'); + $types = EquipmentType::getFullTypeList(); + //$this_item_location = ItemLocations::where('item_id', $equipmentItem->inventoryCode())->get(); + //if ($this_item_location->count() > 0) { + // $this_item_location = $this_item_location->first()->location_id; + //} else { + // $this_item_location = null; + //} + // dd($this_item_location); + // $locations = Locations::pluck('location', 'id'); return view('backend.equipment.items.edit', compact('types', 'equipmentItem')); } + + /** + * Edit the locations ot the item + * + * @param EquipmentItem $equipmentItem + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + */ + public function editLocation(EquipmentItem $equipmentItem) + { + $locations = Locations::all()->where('parent_location', 1)->all(); + + return view('backend.equipment.items.edit-location', compact('equipmentItem', 'locations')); + } + /** * Update the specified resource in storage. * @@ -115,13 +144,12 @@ public function edit(EquipmentItem $equipmentItem) */ public function update(Request $request, EquipmentItem $equipmentItem) { -// dd($request->request); + // dd($request->request); $data = request()->validate([ 'title' => 'string|required', 'brand' => 'string|nullable', 'productCode' => 'string|nullable', 'equipment_type_id' => 'numeric|required', - 'specifications' => 'string|nullable', 'description' => 'string|nullable', 'instructions' => 'string|nullable', @@ -141,15 +169,15 @@ public function update(Request $request, EquipmentItem $equipmentItem) try { if ($request->thumb != null) { - $data['thumb'] = $this->uploadThumb($equipmentItem->thumbURL(), $request->thumb, "equipment_items"); + $data['thumb'] = $this->uploadThumb($equipmentItem->thumb, $request->thumb, "equipment_items"); } // Update checkbox condition $equipmentItem->isElectrical = ($request->isElectrical != null); $equipmentItem->update($data); - return redirect()->route('admin.equipment.items.index')->with('Success', 'Equipment was updated !'); + return redirect()->route('admin.equipment.items.index')->with('Success', 'Equipment was updated !'); } catch (\Exception $ex) { return abort(500); } @@ -175,22 +203,28 @@ public function delete(EquipmentItem $equipmentItem) */ public function destroy(EquipmentItem $equipmentItem) { + try { // Delete the thumbnail form the file system - $this->deleteThumb($equipmentItem->thumbURL()); + $this->deleteThumb($equipmentItem->thumb); $equipmentItem->delete(); - return redirect()->route('admin.equipment.items.index')->with('Success', 'Equipment was deleted !'); + // delete location entries + $this_item_locations = ItemLocations::where('item_id', $equipmentItem->inventoryCode())->get(); + foreach ($this_item_locations as $loc) { + $loc->delete(); + } + + return redirect()->route('admin.equipment.items.index')->with('Success', 'Equipment was deleted !'); } catch (\Exception $ex) { - dd($ex); return abort(500); } } private function deleteThumb($currentURL) { - if ($currentURL != null) { + if ($currentURL != null && $currentURL != config('constants.frontend.dummy_thumb')) { $oldImage = public_path($currentURL); if (File::exists($oldImage)) unlink($oldImage); } diff --git a/app/Http/Controllers/Backend/EquipmentTypeController.php b/app/Http/Controllers/Backend/EquipmentTypeController.php old mode 100644 new mode 100755 index 9fbef917..0fd08946 --- a/app/Http/Controllers/Backend/EquipmentTypeController.php +++ b/app/Http/Controllers/Backend/EquipmentTypeController.php @@ -6,8 +6,10 @@ use App\Models\EquipmentType; use Illuminate\Http\Request; use Illuminate\Support\Facades\File; -use Illuminate\Support\Facades\Storage; use Intervention\Image\Facades\Image; +use App\Models\ItemLocations; +use App\Models\Locations; +use Torann\GeoIP\Location; class EquipmentTypeController extends Controller { @@ -18,8 +20,8 @@ class EquipmentTypeController extends Controller */ public function index() { - $equipmentTypes = EquipmentType::paginate(12); - return view('backend.equipment.types.index', compact('equipmentTypes')); + //$equipmentTypes = EquipmentType::orderBy('id', 'asc')->paginate(16); + return view('backend.equipment.types.index'); } /** @@ -29,7 +31,7 @@ public function index() */ public function create() { - $types = EquipmentType::pluck('title', 'id'); + $types = EquipmentType::getFullTypeList(); return view('backend.equipment.types.create', compact('types')); } @@ -57,7 +59,6 @@ public function store(Request $request) $type = new EquipmentType($data); $type->save(); return redirect()->route('admin.equipment.types.index')->with('Success', 'EquipmentType was created !'); - } catch (\Exception $ex) { return abort(500, "Error 222"); } @@ -82,7 +83,7 @@ public function show(EquipmentType $equipmentType) */ public function edit(EquipmentType $equipmentType) { - $types = EquipmentType::pluck('title', 'id'); + $types = EquipmentType::getFullTypeList(); return view('backend.equipment.types.edit', compact('equipmentType', 'types')); } @@ -105,12 +106,11 @@ public function update(Request $request, EquipmentType $equipmentType) try { if ($request->thumb != null) { - $data['thumb'] = $this->uploadThumb($equipmentType->thumbURL(), $request->thumb, "equipment_types"); + $data['thumb'] = $this->uploadThumb($equipmentType->thumb, $request->thumb, "equipment_types"); } $equipmentType->update($data); return redirect()->route('admin.equipment.types.index')->with('Success', 'EquipmentType was updated !'); - } catch (\Exception $ex) { return abort(500); } @@ -137,19 +137,21 @@ public function destroy(EquipmentType $equipmentType) { try { // Delete the thumbnail form the file system - $this->deleteThumb($equipmentType->thumbURL()); + if ($equipmentType->thumb != null) { + $this->deleteThumb($equipmentType->thumb); + } $equipmentType->delete(); return redirect()->route('admin.equipment.types.index')->with('Success', 'EquipmentType was deleted !'); - } catch (\Exception $ex) { + dd($ex); return abort(500); } } private function deleteThumb($currentURL) { - if ($currentURL != null) { + if ($currentURL != null && $currentURL != config('constants.frontend.dummy_thumb')) { $oldImage = public_path($currentURL); if (File::exists($oldImage)) unlink($oldImage); } diff --git a/app/Http/Controllers/Backend/JobRequestsController.php b/app/Http/Controllers/Backend/JobRequestsController.php new file mode 100755 index 00000000..5d471f99 --- /dev/null +++ b/app/Http/Controllers/Backend/JobRequestsController.php @@ -0,0 +1,233 @@ +id)->get()->reverse(); + return view('backend.jobs.student.index'); + } + + public function student_create() + { + $machines = Machines::pluck('title', 'id'); + $materials = RawMaterials::pluck('title', 'id'); + $lecturers = []; //User::lecturers(); + + foreach (User::lecturers() as $l) { + $lecturers[$l->id] = $l->name; + } + + return view('backend.jobs.student.create', compact('machines', 'materials', 'lecturers')); + } + + public function student_store(Request $request) + { + $data = request()->validate([ + 'machine' => 'numeric|required', + 'material' => 'numeric|required', + 'supervisor' => 'numeric|required', + 'student_notes' => 'string|required', + 'file' => 'required|required|mimes:zip|max:51200', + 'thumb' => 'image|required|mimes:jpeg,jpg,png,jpg,gif,svg|max:2048', + ]); + + try { + if ($request->thumb != null) { + $data['thumb'] = $this->uploadImage(null, $request->thumb, "jobs"); + } + if ($request->file != null) { + $data['file'] = $this->uploadFile(null, $request->file, "jobs"); + } + + $jobReq = new JobRequests($data); + $jobReq->status = 'PENDING'; + $jobReq->requested_time = date("Y-m-d h:i:s"); // 2022-05-12 12:17:17 + $jobReq->student = $request->user()->id; + $jobReq->save(); + + return redirect()->route('admin.jobs.student.confirm', $jobReq); + } catch (\Exception $ex) { + // dd($ex); + return abort(500); + } + } + + public function student_show(JobRequests $jobRequests) + { + return view('backend.jobs.student.show', compact('jobRequests')); + } + + public function student_confirm(JobRequests $jobRequests) + { + if ($jobRequests->status == 'PENDING') { + return view('backend.jobs.student.confirm', compact('jobRequests')); + } else { + $id = $jobRequests->id; + return redirect()->route('admin.jobs.student.index')->with('Success', 'The fabrication request #' . $id . ' already sent for the approval !'); + } + } + + public function student_summary(JobRequests $jobRequests) + { + try { + // Email to supervisor + // TODO: Implement this + + // Change the status + $jobRequests->status = 'WAITING_SUPERVISOR_APPROVAL'; + $jobRequests->save(); + $id = $jobRequests->id; + return redirect()->route('admin.jobs.student.index')->with('Success', 'The fabrication request #' . $id . ' was placed successfully !'); + } catch (\Exception $ex) { + return abort(500); + } + } + + public function student_delete(JobRequests $jobRequests) + { + return view('backend.jobs.student.delete', compact('jobRequests')); + } + + public function student_destroy(JobRequests $jobRequests) + { + try { + // Delete the thumbnail form the file system + $this->deleteFile($jobRequests->thumbURL()); + $this->deleteFile($jobRequests->fileURL()); + + $jobRequests->delete(); + return redirect()->route('admin.jobs.student.index')->with('Success', 'Job request was deleted !'); + } catch (\Exception $ex) { + return abort(500); + } + } + + // ----------------------------------------------------------------------------------------------- + + public function supervisor_index() + { + //$jobs = JobRequests::where('supervisor', \Auth::user()->id)->get()->reverse(); + return view('backend.jobs.supervisor.index'); + } + + public function supervisor_show(JobRequests $jobRequests) + { + return view('backend.jobs.supervisor.show', compact('jobRequests')); + } + + public function supervisor_approve(JobRequests $jobRequests) + { + dd('Approved'); + // TODO: The logic to be implemented + // Send an email to the student + // Send an email to the TO + // Update the status into 'PENDING_FABRICATION' + // Update timestamp details + return redirect()->route('admin.jobs.supervisor.index'); + } + + public function supervisor_reject(JobRequests $jobRequests) + { + dd('Rejected'); + // TODO: The logic to be implemented + // Send an email to the student + // Update the status into 'NOT_APPROVED' + // Update timestamp details + return redirect()->route('admin.jobs.supervisor.index'); + } + + // ----------------------------------------------------------------------------------------------- + + public function officer_index() + { + //$jobs = JobRequests::jobsForTechOfficer(); + return view('backend.jobs.technical-officer.index'); + } + + public function officer_show(JobRequests $jobRequests) + { + return view('backend.jobs.technical-officer.show', compact('jobRequests')); + } + + public function officer_edit(JobRequests $jobRequests) + { + return view('backend.jobs.technical-officer.edit', compact('jobRequests')); + } + + public function officer_update(JobRequests $jobRequests) + { + dd($jobRequests); + // TODO: To be implemented + // Store the additional parameters + // Send an Email to the student (about scheduled time and additional notes) + return redirect()->route('admin.jobs.officer.index'); + } + + public function officer_finish(JobRequests $jobRequests) + { + dd("Finished"); + // TODO: Finish the job + // Send emails to Student and Lecturer about the finish notice + // Update machine timed, material usage, etc... + return redirect()->route('admin.jobs.officer.index'); + } + + + // ----------------------------------------------------------------------------------------------- + // Support Functions + private function deleteFile($currentURL) + { + if ($currentURL != null && $currentURL != config('constants.frontend.dummy_thumb')) { + $file = public_path($currentURL); + if (File::exists($file)) { + unlink($file); + } + } + } + + // Private function to handle thumb images + private function uploadImage($currentURL, $newImage, $folder) + { + // Delete the existing image + $this->deleteFile($currentURL); + + $imageName = time() . '.' . $newImage->extension(); + $newImage->move(public_path('img/' . $folder), $imageName); + $imagePath = "/img/$folder/" . $imageName; + $image = Image::make(public_path($imagePath))->fit(360, 360); + $image->save(); + + return $imageName; + } + + // Private function to handle file upload + private function uploadFile($currentURL, $newFile, $folder) + { + // Delete the existing file + $this->deleteFile($currentURL); + $fileName = time() . '.' . $newFile->extension(); + $newFile->move(public_path('files/' . $folder), $fileName); + return $fileName; + } +} diff --git a/app/Http/Controllers/Backend/LocationsController.php b/app/Http/Controllers/Backend/LocationsController.php new file mode 100755 index 00000000..8da58c5f --- /dev/null +++ b/app/Http/Controllers/Backend/LocationsController.php @@ -0,0 +1,145 @@ +validate([ + 'locationName' => [ + 'required', + 'string', + 'max:255', + 'unique:locations,location' + ], + 'parentLocation' => [ + 'required', + function ($attribute, $value, $fail) { + $allLocations = Locations::pluck('id')->toArray(); + if (!in_array($value, $allLocations)) { + $fail(__('The parent location does not exist.')); + } + } + ] + ]); + + Locations::create([ + 'location' => $data['locationName'], + 'parent_location' => $data['parentLocation'] + ]); + + return redirect()->route('admin.locations.index')->with('Success', 'Equipment was created !'); + } catch (\Exception $e) { + return abort(500); + } + + } + + /** + * @param Locations $location + * @return void + */ + public function show(Locations $location) + { +// not used + } + + /** + * @param Locations $location + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + */ + public function edit(Locations $location) + { + $locations = Locations::getFullLocationStringFromPluck(); + return view('backend.locations.edit', compact('location', 'locations')); + } + + /** + * @param Request $request + * @param Locations $location + * @return \Illuminate\Http\RedirectResponse|never + */ + public function update(Request $request, Locations $location) + { + try { + $data = $request->validate([ + 'locationName' => [ + 'required', + 'string', + 'max:255' + ], + 'parentLocation' => [ + 'required', + function ($attribute, $value, $fail) { + $allLocations = Locations::pluck('id')->toArray(); + if (!in_array($value, $allLocations)) { + $fail(__('The parent location does not exist.')); + } + } + ] + ]); + $location->update([ + 'location' => $data['locationName'], + 'parent_location' => $data['parentLocation'] + ]); + + return redirect()->route('admin.locations.index')->with('Success', 'Location was updated !'); + } catch (\Exception $e) { + return abort(500); + } + } + + /** + * @param Locations $location + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + */ + public function delete(Locations $location) + { + return view('backend.locations.delete', compact('location')); + } + + /** + * @param Locations $location + * @return \Illuminate\Http\RedirectResponse|never + */ + public function destroy(Locations $location) + { + try { + $location->delete(); + return redirect()->route('admin.locations.index')->with('Success', 'Location was deleted !'); + } catch (\Exception $e) { + return abort(500); + } + } + +} \ No newline at end of file diff --git a/app/Http/Controllers/Backend/MachinesController.php b/app/Http/Controllers/Backend/MachinesController.php new file mode 100755 index 00000000..3af79bab --- /dev/null +++ b/app/Http/Controllers/Backend/MachinesController.php @@ -0,0 +1,197 @@ +validate([ + 'code' => 'string|nullable|max:8', + 'title' => 'string|required', + 'type' => Rule::in(['CNC', 'FDM_3D_PRINTER', 'LASER_CUTTER', 'PCB_MILL']), + 'build_width' => 'numeric|nullable|min:0', + 'build_length' => 'numeric|nullable|min:0', + 'build_height' => 'numeric|nullable|min:0', + 'power' => 'numeric|nullable|min:0', + 'thumb' => 'image|nullable|mimes:jpeg,jpg,png,jpg,gif,svg|max:2048', + 'specifications' => 'string|nullable', + 'status' => Rule::in(['AVAILABLE', 'NOT_AVAILABLE', 'CONDITIONALLY_AVAILABLE']), + 'notes' => 'string|nullable', + ]); + + try { + if ($request->thumb != null) { + $data['thumb'] = $this->uploadThumb(null, $request->thumb, "machines"); + } + + $machine = new Machines($data); + $machine->save(); + + return redirect()->route('admin.machines.edit.location', $machine)->with('Success', 'Machine was created !'); + } catch (\Exception $ex) { + return abort(500); + } + } + + /** + * Display the specified resource. + * + * @param \App\Models\Machines $machine + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + */ + public function show(Machines $machines) + { + $locationCount = $this->getNumberOfLocationsForItem($machines); + + $locations_array = array(); + for ($i = 0; $i < $locationCount; $i++) { + $locations_array[] = $this->getFullLocationPathAsString($machines, $i); + } + return view('backend.machines.show', compact('machines', 'locations_array')); + } + + /** + * Show the form for editing the specified resource. + * + * @param \App\Models\Machines $machine + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\Response + */ + public function edit(Machines $machines) + { + $typeOptions = Machines::types(); + $availabilityOptions = Machines::availabilityOptions(); + + return view('backend.machines.edit', compact('machines', 'typeOptions', 'availabilityOptions')); + } + + public function editLocations(Machines $machines) + { + $locations = Locations::all()->where('parent_location', 1)->all(); + + return view('backend.machines.edit-location', compact('machines', 'locations')); + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param \App\Models\Machines $machine + * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|void + */ + public function update(Request $request, Machines $machines) + { + $data = request()->validate([ + 'code' => 'string|nullable|max:8', + 'title' => 'string|required' + + ]); + + try { + if ($request->thumb != null) { + $data['thumb'] = $this->uploadThumb($machines->thumb, $request->thumb, "machine"); + } + + $machines->update($data); + + return redirect()->route('admin.machines.index')->with('Success', 'Machine was updated !'); + } catch (\Exception $ex) { + return abort(500); + } + } + + /** + * Confirm to delete the specified resource from storage. + * @param \App\Models\Machines $machines + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + */ + public function delete(Machines $machines) + { + return view('backend.machines.delete', compact('machines')); + } + + /** + * Remove the specified resource from storage. + * + * @param \App\Models\Machines $machines + * @return \Illuminate\Http\RedirectResponse|void + */ + public function destroy(Machines $machines) + { + try { + // Delete the thumbnail form the file system + $this->deleteThumb($machines->thumb); + + $machines->delete(); + + // delete location entry + $this_item_location = ItemLocations::where('item_id', $machines->inventoryCode())->delete(); + + return redirect()->route('admin.machines.index')->with('Success', 'Machine was deleted !'); + } catch (\Exception $ex) { + return abort(500); + } + } + + private function deleteThumb($currentURL) + { + if ($currentURL != null && $currentURL != config('constants.frontend.dummy_thumb')) { + $oldImage = public_path($currentURL); + if (File::exists($oldImage)) unlink($oldImage); + } + } + + // Private function to handle thumb images + private function uploadThumb($currentURL, $newImage, $folder) + { + // Delete the existing image + $this->deleteThumb($currentURL); + + $imageName = time() . '.' . $newImage->extension(); + $newImage->move(public_path('img/' . $folder), $imageName); + $imagePath = "/img/$folder/" . $imageName; + $image = Image::make(public_path($imagePath))->fit(360, 360); + $image->save(); + + return $imageName; + } +} diff --git a/app/Http/Controllers/Backend/OrderController.php b/app/Http/Controllers/Backend/OrderController.php new file mode 100755 index 00000000..5e0aef0f --- /dev/null +++ b/app/Http/Controllers/Backend/OrderController.php @@ -0,0 +1,139 @@ +validate([ + + 'picked_date' => 'string|nullable', // TODO: Validate properly + 'due_date_to_return' => 'string|required', + 'returned_date' => 'string|nullable', + 'status' => 'string|required', + ]); + try { + $data['ordered_date'] = Carbon::now()->format('Y-m-d'); + $data['user_id'] = $request->user()->id; + $order = new Order($data); + $order->save(); + return redirect()->route('admin.orders.index')->with('Success', 'Order was created !'); + } catch (\Exception $ex) { + return abort(500, "Error 222"); + } + } + + /** + * Display the specified resource. + * + * @param \App\Models\Order $order + * @return \Illuminate\Http\Response + */ + public function show(Order $order) + { + return view('backend.orders.show', compact('order')); + } + + /** + * Show the form for editing the specified resource. + * + * @param \App\Models\Order $order + * @return \Illuminate\Http\Response + */ + public function edit(Order $order) + { + return view('backend.orders.edit', compact('order')); + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param \App\Models\Order $order + * @return \Illuminate\Http\Response + */ + public function update(Request $request, Order $order) + { + $data = request()->validate([ + 'ordered_date' => 'string|required', + 'picked_date' => 'string|nullable', // TODO: Validate properly + 'due_date_to_return' => 'string|required', + 'returned_date' => 'string|nullable', + 'status' => 'string|required', + ]); + + try { + $order->update($data); + return redirect()->route('admin.orders.index')->with('Success', 'Order was updated !'); + + } catch (\Exception $ex) { + return abort(500); + } + } + + /** + * Confirm to delete the specified resource from storage. + * + * @param \App\Models\Order $order + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + */ + public function delete(Order $order) + { + return view('backend.orders.delete', compact('order')); + } + + + /** + * Remove the specified resource from storage. + * + * @param \App\Models\Order $order + * @return \Illuminate\Http\Response + */ + public function destroy(Order $order) + { + try { + + $order->delete(); + return redirect()->route('admin.orders.index')->with('Success', 'Order was deleted !'); + + } catch (\Exception $ex) { + return abort(500); + } + } +} diff --git a/app/Http/Controllers/Backend/RawMaterialsController.php b/app/Http/Controllers/Backend/RawMaterialsController.php new file mode 100755 index 00000000..369cb7e9 --- /dev/null +++ b/app/Http/Controllers/Backend/RawMaterialsController.php @@ -0,0 +1,208 @@ +validate([ + 'code' => 'string|nullable|max:8', + 'title' => 'string|required', + 'color' => 'string|nullable', + 'description' => 'string|nullable', + 'specifications' => 'string|nullable', + 'quantity' => 'numeric|nullable', + 'unit' => 'string|nullable', + 'availability' => Rule::in(['AVAILABLE', 'NOT_AVAILABLE', 'CONDITIONALLY_AVAILABLE']), + 'thumb' => 'image|nullable|mimes:jpeg,jpg,png,jpg,gif,svg|max:2048', + 'notes' => 'string|nullable', + ]); + + try { + if ($request->thumb != null) { + $data['thumb'] = $this->uploadThumb(null, $request->thumb, "raw_materials"); + } + + $materials = new RawMaterials($data); + $materials->save(); + return redirect()->route('admin.raw_materials.edit.location', $materials)->with('Success', 'Raw Material was created !'); + } catch (\Exception $ex) { + return abort(500); + } + } + + /** + * Display the specified resource. + * + * @param \App\Models\RawMaterials $rawMaterials + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + */ + public function show(RawMaterials $rawMaterials) + { + $locationCount = $this->getNumberOfLocationsForItem($rawMaterials); + + $locations_array = array(); + for ($i = 0; $i < $locationCount; $i++) { + $locations_array[] = $this->getFullLocationPathAsString($rawMaterials, $i); + } + return view('backend.raw_materials.show', compact('rawMaterials', 'locations_array')); + } + + /** + * Show the form for editing the specified resource. + * + * @param \App\Models\RawMaterials $rawMaterials + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + */ + public function edit(RawMaterials $rawMaterials) + { + // $this_item_location = ItemLocations::where('item_id', $rawMaterials->inventoryCode())->get()[0]['location_id']; + //// dd($this_item_location); + // $locations = Locations::pluck('location', 'id'); + return view('backend.raw_materials.edit', compact('rawMaterials')); + } + + public function editLocations(RawMaterials $rawMaterials) + { + $locations = Locations::all()->where('parent_location', 1)->all(); + + return view('backend.raw_materials.edit-location', compact('rawMaterials', 'locations')); + } + + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param \App\Models\RawMaterials $rawMaterials + * @return \Illuminate\Http\RedirectResponse|void + */ + public function update(Request $request, RawMaterials $rawMaterials) + { + // dd($request, $rawMaterials); + + $data = request()->validate([ + 'code' => 'string|nullable|max:8', + 'title' => 'string|required', + 'color' => 'string|nullable', + 'description' => 'string|nullable', + 'specifications' => 'string|nullable', + 'quantity' => 'numeric|nullable', + 'unit' => 'string|nullable', + 'availability' => Rule::in(['AVAILABLE', 'NOT_AVAILABLE', 'CONDITIONALLY_AVAILABLE']), + 'thumb' => 'image|nullable|mimes:jpeg,jpg,png,jpg,gif,svg|max:2048', + 'notes' => 'string|nullable', + ]); + + // dd($data); + + try { + if ($request->thumb != null) { + $data['thumb'] = $this->uploadThumb($rawMaterials->thumb, $request->thumb, "raw_materials"); + } + + $rawMaterials->update($data); + + + return redirect()->route('admin.raw_materials.index')->with('Success', 'Raw Material was updated !'); + } catch (\Exception $ex) { + return abort(500); + } + } + + /** + * Confirm to delete the specified resource from storage. + * @param \App\Models\RawMaterials $rawMaterials + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + */ + public function delete(RawMaterials $rawMaterials) + { + return view('backend.raw_materials.delete', compact('rawMaterials')); + } + + /** + * Remove the specified resource from storage. + * + * @param \App\Models\RawMaterials $rawMaterials + * @return \Illuminate\Http\RedirectResponse|void + */ + public function destroy(RawMaterials $rawMaterials) + { + try { + // Delete the thumbnail form the file system + $this->deleteThumb($rawMaterials->thumb); + + $rawMaterials->delete(); + + // delete location entry + $this_item_location = ItemLocations::where('item_id', $rawMaterials->inventoryCode())->delete(); + + return redirect()->route('admin.raw_materials.index')->with('Success', 'Raw material was deleted !'); + } catch (\Exception $ex) { + return abort(500); + } + } + + private function deleteThumb($currentURL) + { + if ($currentURL != null && $currentURL != config('constants.frontend.dummy_thumb')) { + $oldImage = public_path($currentURL); + if (File::exists($oldImage)) unlink($oldImage); + } + } + + // Private function to handle thumb images + private function uploadThumb($currentURL, $newImage, $folder) + { + + // Delete the existing image + $this->deleteThumb($currentURL); + + $imageName = time() . '.' . $newImage->extension(); + $newImage->move(public_path('img/' . $folder), $imageName); + $imagePath = "/img/$folder/" . $imageName; + $image = Image::make(public_path($imagePath))->fit(360, 360); + $image->save(); + + return $imageName; + } +} diff --git a/app/Http/Controllers/Backend/ReservationController.php b/app/Http/Controllers/Backend/ReservationController.php new file mode 100755 index 00000000..f73e40a0 --- /dev/null +++ b/app/Http/Controllers/Backend/ReservationController.php @@ -0,0 +1,365 @@ +paginate(16); + return view('backend.reservation.index', compact('reservation')); + } + + /** + * Display a listing of the reservations of the particular user. + * + * @return \Illuminate\Http\Response + */ + public function index_user() + { + $userLoggedin = auth()->user(); + // dd($userLoggedin); + $reservation = Reservation::where('user_id', $userLoggedin['id'])->orderBy('start_date', 'desc')->paginate(16); + return view('backend.reservation.user.index', compact('reservation', 'userLoggedin')); + } + + /** + * Redirection to the updating interface. + * + * @return \Illuminate\Http\Response + */ + public function edit(Reservation $reservation) + { + + $userLoggedin = auth()->user(); + + + $stations = Stations::pluck('stationName', 'id'); + $station = Stations::find($reservation->station_id); + + if ($userLoggedin['id'] != $reservation->user_id) { + return redirect()->route('frontend.reservation.index')->with('Error', 'You can not view that reservation for updating!'); + } else { + return view('backend.reservation.user.edit', compact('reservation', 'stations', 'station')); + } + } + + public function edit_main(Reservation $reservation) + { + + $stations = Stations::pluck('stationName', 'id'); + $station = Stations::find($reservation->station_id); + return view('backend.reservation.edit', compact('reservation', 'stations', 'station')); + } + + + /** + * Display the selected reservation. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + + public function show(Reservation $reservation) + { + return view('backend.reservation.show', compact('reservation')); + } + + public function show_user(Reservation $reservation) + { + return view('backend.reservation.user.show', compact('reservation')); + } + + /** + * Redirect to the approving interface for maintainer. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + + public function confirm(Reservation $reservation) + { + + $stations = Stations::pluck('stationName', 'id'); + $station = Stations::find($reservation->station_id); + return view('backend.reservation.confirm', compact('reservation', 'stations', 'station')); + } + + + /** + * Approve interface with form for the maintainer. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + + public function approve(Request $request, Reservation $reservation) + { + $data = request()->validate([ + 'comments' => 'string|nullable', + 'status' => 'string|required' + ]); + + $data = [ + 'comments' => $request->comments, + 'status' => $request->status, + + ]; + return redirect()->route('admin.reservation.index')->with('Success', 'Reservation was approved !'); + } + + + /** + * Updating the reservation. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + + public function update(Request $request, Reservation $reservation) + { + $userLoggedin = auth()->user(); + + $dateOriginal = (new DateTime($reservation->start_date))->format('Y-m-d'); + $dateOriginal1 = (new DateTime($reservation->start_date))->format('Y-m-d H:i:s'); + + // Data validation + $data = request()->validate([ + 'station_id' => 'numeric|required', + 'start_date' => 'required|date_format:Y-m-d H:i:s', + 'end_date' => 'required|date_format:Y-m-d H:i:s', + 'E_numbers' => 'required|regex:^E/\d{2}/\d{3}$^', + 'thumb' => 'image|nullable|mimes:jpeg,jpg,png,jpg,gif,svg|max:5120', + 'thumb_after' => 'image|nullable|mimes:jpeg,jpg,png,jpg,gif,svg|max:5120' + + ]); + + /************* Check whether any changes were made to the date ********/ + $dateNew = (new DateTime($data['start_date']))->format('Y-m-d'); + $dateNew1 = (new DateTime($data['start_date']))->format('Y-m-d H:i:s'); + + $date1 = Carbon::createFromFormat('Y-m-d', $dateOriginal); + $date2 = Carbon::createFromFormat('Y-m-d', $dateNew); + $result = $date1->eq($date2); + + /*****************************************************************************/ + + // Calculate the duration of the reservation in minutes + $start = new DateTime($request['start_date']); + $end = new DateTime($request['end_date']); + $diff = $start->diff($end); + $minutes = ($diff->h * 60) + ($diff->s / 60) + ($diff->i) + ($diff->d * 24 * 60) + ($diff->m * 30 * 24 * 60) + ($diff->y * 365 * 24 * 60); + + //Check for overlap of events + $res = Reservation::whereDate('start_date', $start)->where('station_id', $data['station_id'])->get(); + $flag = false; + foreach ($res as $r) { + if ($r->user_id != $userLoggedin['id']) { + $flag = $this->isAnOverlapEvent($start, $end, $r); + } + } + + // See if the user has already made a reservation on that day for this station + $bookings1 = Reservation::whereDate('start_date', $start)->where('user_id', $userLoggedin['id'])->where('station_id', $data['station_id'])->get(); + + // See whether the reservation is being made too early (more than a month in advance) + $todayDate = date('Y-m-d H:i:s'); + $today = new DateTime($todayDate); + $today->add(new DateInterval('PT5H30M')); + + $resDiff = $today->diff($start); + $minutesDiff = ($resDiff->h * 60) + ($resDiff->s / 60) + ($resDiff->i) + ($resDiff->d * 24 * 60) + ($resDiff->m * 30 * 24 * 60) + ($resDiff->y * 365 * 24 * 60); + + // Ensuring a reservation made in the past can not be updated + if ($today > $start) { + $minutesDiff = -1; + } + + + $data = [ + 'station_id' => $request['station_id'], + 'start_date' => $request['start_date'], + 'end_date' => $request['end_date'], + 'E_numbers' => $request['E_numbers'], + 'duration' => $minutes, + ]; + + if ($request->thumb != null) { + $data['thumb'] = $this->uploadThumb($reservation->thumb, $request->thumb, "reservations"); + } + + if ($request->thumb_after != null) { + $thumb = ($reservation->thumb_after == NULL) ? NULL : $reservation->thumbURL_after(); + $data['thumb_after'] = $this->uploadThumb($thumb, $request->thumb_after, "reservations_after"); + } + + + // Test case check + if ($userLoggedin['id'] != $reservation->user_id) { + return redirect()->route('frontend.reservation.index')->with('Error', 'You can not update this reservation'); + } elseif ($today >= $start) { + return redirect()->route('frontend.reservation.index')->with('Error', 'Reservation was not updated! You can not make/edit a reservation for a date that has passed.'); + } elseif (($minutesDiff > 43200) && $start > $today) { + return redirect()->route('frontend.reservation.index')->with('Error', 'You can not make a reservation for that date this early.'); + } elseif ($data['duration'] > 240) { + return redirect()->route('frontend.reservation.index')->with('Error', 'Reservation was not updated! Reservation can not exceed 4 hours'); + } elseif ($flag) { + return redirect()->route('frontend.reservation.index')->with('Error', 'Reservation was not updated! Time slot not available'); + } elseif ((count($bookings1) == 1) && $result && !$flag && ($minutesDiff < 43200)) { + $reservation->update($data); + return redirect()->route('frontend.reservation.index')->with('Success', 'Reservation was updated !'); + } elseif ((count($bookings1) == 0 && !$flag && ($minutesDiff < 43200))) { + $reservation->update($data); + return redirect()->route('frontend.reservation.index')->with('Success', 'Reservation was updated !'); + } elseif ((count($bookings1) == 1) && !$result) { + return redirect()->route('frontend.reservation.index')->with('Error', 'Reservation was not updated! Can not make multiple reservations in one day'); + } + } + + /** + * Updating the comments and approval. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + + public function update_main(Request $request, Reservation $reservation) + { + $data = request()->validate([ + 'status' => 'string|nullable', + 'comments' => 'string|nullable' + ]); + + $data = [ + 'status' => $request['status'], + 'comments' => $request['comments'], + + ]; + + $reservation->update($data); + return redirect()->route('admin.reservation.index')->with('Success', 'Reservation status was saved !'); + } + + public function isAnOverlapEvent(DateTime $eventStartDay, DateTime $eventEndDay, Reservation $res) + { + // var events = $('#calendar').fullCalendar('clientEvents'); + $resStart = new DateTime($res->start_date); + $resEnd = new DateTime($res->end_date); + + // start-time in between any of the events + if ($eventStartDay > $resStart && $eventStartDay < $resEnd) { + return true; + } + //end-time in between any of the events + if ($eventEndDay > $resStart && $eventEndDay < $resEnd) { + return true; + } + //any of the events in between/on the start-time and end-time + if ($eventStartDay <= $resStart && $eventEndDay >= $resEnd) { + return true; + } + + return false; + } + + /** + * Confirm to delete the specified resource from storage. + * + * @param \App\Models\EquipmentItem $equipmentItem + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + */ + public function delete(Reservation $reservation) + { + $userLoggedIn = auth()->user(); + $station = Stations::find($reservation->station_id); + + if ($userLoggedIn['id'] == $reservation->user_id) { + return view('backend.reservation.user.delete', compact('reservation', 'station')); + } else { + return redirect()->route('frontend.reservation.index')->with('Error', 'You can not delete this reservation!'); + } + } + + /** + * Delete reservation from the storage. + * + * @param \App\Models\EquipmentItem $equipmentItem + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + */ + + public function destroy(Reservation $reservation) + { + $userLoggedIn = auth()->user(); + $booking = Reservation::find($reservation->id); + + $this->deleteThumb($reservation->thumb); + $this->deleteThumb($reservation->thumb_after); + + if (!$booking) { + return response()->json([ + 'error' => 'Unable to locate the event' + ], 404); + } + + $todayDate = date('Y-m-d H:i:s'); + $today = new DateTime($todayDate); + $start = new DateTime($reservation['start_date']); + + if ($userLoggedIn['id'] == $booking->user_id && (($reservation->status != null && $reservation->status == 'approved') || ($start > $today))) { + $booking->delete(); + return redirect()->route('frontend.reservation.index')->with('Success', 'Reservation was deleted !'); + } elseif (($reservation->status == null || $reservation->status == 'pending' || $reservation->status == 'rejected') && $start > $today) { + return redirect()->route('frontend.reservation.index')->with('Error', 'You can not delete this reservation as it has not been approved!'); + } else { + return redirect()->route('frontend.reservation.index')->with('Error', 'You can not delete this reservation!'); + } + } + + private function deleteThumb($currentURL) + { + if ($currentURL != null && $currentURL != config('constants.frontend.dummy_thumb')) { + $oldImage = public_path($currentURL); + if (File::exists($oldImage)) unlink($oldImage); + } + } + + // Private function to handle thumb images + private function uploadThumb($currentURL, $newImage, $folder) + { + // Delete the existing image + $this->deleteThumb($currentURL); + + $imageName = time() . '.' . $newImage->extension(); + $newImage->move(public_path('img/' . $folder), $imageName); + $imagePath = "/img/$folder/" . $imageName; + + + $image = Image::make(public_path($imagePath)); + $image->save(); + + return $imageName; + } +} diff --git a/app/Http/Controllers/Backend/SearchController.php b/app/Http/Controllers/Backend/SearchController.php new file mode 100755 index 00000000..8c6a7116 --- /dev/null +++ b/app/Http/Controllers/Backend/SearchController.php @@ -0,0 +1,105 @@ +keywords; + + if (strlen($keywords) == 0) { + return view('backend.search.index')->with('status', 'Search string is empty. Please type something'); + } + + $searchResults = (new Search()) + ->registerModel(ComponentItem::class, ['title', 'brand']) + ->registerModel(EquipmentItem::class, ['title', 'brand']) + ->registerModel(Machines::class, ['title']) + ->registerModel(ConsumableItem::class, ['title']) + ->registerModel(RawMaterials::class, ['title', 'description']) + ->search($keywords); + + return view('backend.search.results', compact('searchResults', 'keywords')); + } + + public function reverseSearchIndex() + { + $loc = Locations::where('parent_location', 1)->get(); + $locations = []; + + // TODO: Make this better + // For now, only support upto 4 levels + // I think we can just extend this to like 10 levels or something like that ¯\_(ツ)_/¯ + foreach ($loc as $key => $value) { + $locations[$value->id] = $value->location; + // Level 2 + if ($value->getChildrenLocations()->count() > 0) { + foreach ($value->getChildrenLocations() as $l) { + $locations[$l->id] = $l->getFullLocationAddress(); + // Level 3 + if ($l->getChildrenLocations()->count() > 0) { + foreach ($l->getChildrenLocations() as $ll) { + $locations[$ll->id] = $ll->getFullLocationAddress(); + // Level 4 + if ($ll->getChildrenLocations()->count() > 0) { + foreach ($ll->getChildrenLocations() as $lll) { + $locations[$lll->id] = $lll->getFullLocationAddress(); + } + } + } + } + } + } + } + // dd($locations); + return view('backend.search.reverseIndex', compact('locations')); + } + + public function reverseResults(Request $request) + { + $allItems = array(); +// this function is going to very resource heavy I think +// TODO: optimize this. This will take a very long time if there are lots of items. + $location = $request->location; + +// dd($location); + + $full_location_path_array = $this->getFullLocationPathByLocationID($location); + $locationName = implode(' > ', array_reverse($full_location_path_array)); + + +// get all the items with the corresponding location id + $allItemsLocationIDs = ItemLocations::where('location_id', $location)->get(); + +// iterate on each item and find the entry from DB + foreach ($allItemsLocationIDs as $eachItem) { + $itemModel = $eachItem->get_item(); + if ($itemModel != null) { + $allItems[] = $itemModel; + } + } +// dd($allItems); + + return view('backend.search.reverseResults', compact('allItems', 'locationName')); + } + +} + diff --git a/app/Http/Controllers/Backend/StationController.php b/app/Http/Controllers/Backend/StationController.php new file mode 100755 index 00000000..cedc4bc0 --- /dev/null +++ b/app/Http/Controllers/Backend/StationController.php @@ -0,0 +1,176 @@ +paginate(16); + return view('backend.station.index', compact('station')); + } + + /** + * Show the form for creating a new station. + * + * @return Application|Factory|View|\Illuminate\Http\Response + */ + public function create() + { + $station = Stations::pluck('stationName', 'id'); + $equipment = EquipmentItem::pluck('title', 'id'); + return view('backend.station.create', compact('station', 'equipment')); + } + + /** + * Store a newly created station in storage. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\RedirectResponse + */ + public function store(Request $request) + { + + $data = request()->validate([ + 'stationName' => 'string|required', + 'description' => 'string|nullable', + 'thumb' => 'image|nullable|mimes:jpeg,jpg,png,jpg,gif,svg|max:2048', + 'capacity' => 'numeric|required' + ]); + + try { + if ($request->thumb != null) { + $data['thumb'] = $this->uploadThumb(null, $request->thumb, "stations"); + } + $type = new Stations($data); + $type->save(); + return redirect()->route('admin.station.index')->with('Success', 'Station was created !'); + } catch (\Exception $ex) { + //dd($ex); + return abort(500); + } + } + + /** + * Display the specified station. + * + * @param int $id + * @return Application|Factory|View|\Illuminate\Http\Response + */ + + public function show(Stations $station) + { + return view('backend.station.show', compact('station')); + } + + /** + * Show the form for editing the specified station. + * + * @param int $id + * @return Application|Factory|View|\Illuminate\Http\Response + */ + public function edit(Stations $station) + { + $stations = Stations::pluck('stationName', 'id'); + return view('backend.station.edit', compact('station')); + } + + /** + * Update the specified station in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\RedirectResponse + */ + public function update(Request $request, Stations $station) + { + $data = request()->validate([ + 'stationName' => 'string|required', + 'description' => 'string|nullable', + 'thumb' => 'image|nullable|mimes:jpeg,jpg,png,jpg,gif,svg|max:2048', + 'capacity' => 'numeric|required' + ]); + + try { + if ($request->thumb != null) { + $data['thumb'] = $this->uploadThumb($station->thumb, $request->thumb, "stations"); + } + $station->update($data); + return redirect()->route('admin.station.index')->with('Success', 'Station was updated !'); + } catch (\Exception $ex) { + return abort(500); + } + } + + /** + * Remove the specified station from storage. + * + * @param int $id + * @return Application|Factory|View|\Illuminate\Http\Response + */ + public function delete(Stations $station) + { + return view('backend.station.delete', compact('station')); + } + + /** + * Remove the specified station from storage. + * + * @param \App\Models\Station $station + * @return \Illuminate\Http\RedirectResponse|null + */ + public function destroy(Stations $station) + { + try { + // Delete the thumbnail form the file system + $this->deleteThumb($station->thumb); + + $station->delete(); + return redirect()->route('admin.station.index')->with('Success', 'Station was deleted !'); + } catch (\Exception $ex) { + return abort(500); + } + } + + private function deleteThumb($currentURL) + { + if ($currentURL != null && $currentURL != config('constants.frontend.dummy_thumb')) { + $oldImage = public_path($currentURL); + if (File::exists($oldImage)) unlink($oldImage); + } + } + + // Private function to handle thumb images + private function uploadThumb($currentURL, $newImage, $folder) + { + + // Delete the existing image + $this->deleteThumb($currentURL); + + $imageName = time() . '.' . $newImage->extension(); + $newImage->move(public_path('img/' . $folder), $imageName); + $imagePath = "/img/$folder/" . $imageName; + $image = Image::make(public_path($imagePath))->fit(640, 480); + $image->save(); + + return $imageName; + } +} diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php old mode 100644 new mode 100755 index 0298f1e3..654dec2c --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -2,6 +2,9 @@ namespace App\Http\Controllers; +use App\Models\ItemLocations; +use App\Models\Locations; +use Illuminate\Database\Eloquent\Model; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Foundation\Validation\ValidatesRequests; @@ -13,4 +16,67 @@ class Controller extends BaseController { use AuthorizesRequests, DispatchesJobs, ValidatesRequests; + + + /** + * Find the full location path by location ID. + * @param int $id + * @return array + */ + public function getFullLocationPathByLocationID(int $id){ + $locationID = $id; + $locations_array = array(); + while (true) { + $thisLocation = Locations::where('id', $locationID)->get()[0]; + $locations_array[] = $thisLocation->location; + $locationID = $thisLocation->parent_location; + + if ($locationID == null) break; + } + + return $locations_array; + } + + /** + * Find the full location path by eloquent model + * + * @param Model $item + * @return array + */ + public function getFullLocationPathAsArray(Model $item, int $index) + { + $locations_array = array(); +// find the item location id from the item_locations table + $locationID = ItemLocations::where('item_id', $item->inventoryCode())->get(); + if ($locationID->count() > 0) { + $locationID = $locationID[$index]->location_id; + } else { + return $locations_array; + } + return $this->getFullLocationPathByLocationID($locationID); + } + + /** + * Get the path for the item as a string with " > " separators + * + * @param Model $item + * @param int $index + * @return string + */ + public function getFullLocationPathAsString(Model $item, int $index){ + $location_array = $this->getFullLocationPathAsArray($item,$index); + return implode(' > ', array_reverse($location_array)); + } + + /** + * Get the number of records for this item in the item_locations table + * + * @param Model $item + * @return mixed + */ + public function getNumberOfLocationsForItem(Model $item){ + $locationID = ItemLocations::where('item_id', $item->inventoryCode())->get(); + return $locationID->count(); + } + } diff --git a/app/Http/Controllers/Frontend/CalendarController.php b/app/Http/Controllers/Frontend/CalendarController.php new file mode 100755 index 00000000..2e927a53 --- /dev/null +++ b/app/Http/Controllers/Frontend/CalendarController.php @@ -0,0 +1,243 @@ +user(); + $events = []; + + // Get all the reservations for that particular station + + $bookings = Reservation::where('station_id', $station->id)->where('start_date', '>', Carbon::now()->subDays(8))->where('start_date', '>', Carbon::now()->subDays(8))->get(); + + foreach ($bookings as $booking) { + if ($booking->user_id != $userLoggedin['id']) { + $color = '#435258'; + } else { + $color = '#3E9CC2'; + } + + $userVar = User::find($booking->user_id); + $events[] = [ + 'id' => $booking->id, + 'title' => 'Reservation made by ' . $userVar->email . ' for ' . $booking->E_numbers, + 'start' => $booking->start_date, + 'end' => $booking->end_date, + 'stationId' => $station->id, + 'auth' => $booking->user_id, + 'color' => $color, + ]; + } + + $today = date('Y-m-d H:i:s'); + return view('frontend.calendar.index', ['events' => $events, 'station' => $station, 'userLoggedin' => $userLoggedin, 'today' => $today]); + } + + public function list(Stations $station) + { + $events = array(); + $bookings = Reservation::where('station_id', $station->id)->where('start_date', '>', Carbon::now()->subDays(8))->get(); + + foreach ($bookings as $booking) { + $userVar = User::find($booking->user_id); + $events[] = [ + 'id' => $booking->id, + 'title' => 'Reservation made by ' . $userVar->email . ' for ' . $booking->E_numbers, + 'start' => $booking->start_date, + 'end' => $booking->end_date, + 'stationId' => $station->id, + 'auth' => $booking->user_id, + ]; + } + return response()->json($events); + } + + public function store(Request $request) + { + $station = Session::get('station'); + $userLoggedin = auth()->user(); + + $stringLength = Str::length($request['title']); + + $request->validate([ + 'title' => 'required|regex:^E/\d{2}/\d{3}$^', + ]); + + + $date = $request->begin; + + // See if the user has already made a reservation on that day for this station + $bookings1 = Reservation::whereDate('start_date', $date)->where('user_id', $userLoggedin['id'])->where('station_id', $station->id)->get(); + + + // If the user has not made a reservation before + if ($bookings1->isEmpty()) { + $booking = Reservation::create([ + + 'user_id' => $userLoggedin['id'], + 'start_date' => $request->start_date, + 'end_date' => $request->end_date, + 'station_id' => $station->id, + 'E_numbers' => $request->title, + 'duration' => $request->m, + + ]); + + $color = null; + + if ($booking->title == 'Try') { + $color = '#33C0FF'; + } + + //***********mails**************** + + // Nuwan: This part is working. So I added a 'if condition' to this in such a way that + // it will be only executed in a web server. + // Environment can be setup in the .env file + + + if (App::environment(['local', 'staging'])) { + // dd('Not sending emails'); + } else { + + try { + $enums = explode(',', $request->title); + + foreach ($enums as $enum) { + + //get enumber + $enum1 = explode('/', $enum); + $batch = $enum1[1]; + $regnum = $enum1[2]; + + //set api url + $apiurl = 'https://api.ce.pdn.ac.lk/people/v1/students/E' . '' . $batch . '/' . $regnum . '/'; + + //api call + $response = Http::withoutVerifying() + ->get($apiurl); + + //extract email address + $email = ($response['emails']['faculty']['name'] . '@' . $response['emails']['faculty']['domain']); + + //get user + $user = auth()->user(); + + //send mail + Mail::to($email) + ->send(new StationReservationMail(auth()->user(), $station, $booking)); + } + } catch (\Exception $e) { + return response()->json([ + 'error' => 'enumber null' + ], 404); + } + } + + + + //**********mails**************** + + return response()->json([ + 'id' => $booking->id, + 'start' => $booking->start_date, + 'end' => $booking->end_date, + 'title' => $booking->title, + 'station_id' => $station->id, + 'color' => $color ? $color : '', + ]); + } else { + // Print message + return response()->json([ + 'error' => 'Unable to locate the event', + ], 404); + } + } + + public function update(Request $request, $id) + { + + $station = Session::get('station'); + $userLoggedin = auth()->user(); + + + $booking = Reservation::find($id); + + //See whether update is made on the same day + $dateOriginal = (new DateTime($booking->start_date))->format('Y-m-d'); + $dateNew = (new DateTime($request['start_date']))->format('Y-m-d'); + + $date1 = Carbon::createFromFormat('Y-m-d', $dateOriginal); + $date2 = Carbon::createFromFormat('Y-m-d', $dateNew); + + $result = $date1->eq($date2); + + $date = $request->begin; + + // See if the user has already made a reservation on that day for this station + $bookings1 = Reservation::whereDate('start_date', $date)->where('user_id', $userLoggedin['id'])->where('station_id', $station->id)->get(); + + if (!$booking) { + return response()->json([ + 'error' => 'Unable to locate the event', + ], 404); + } + + $booking->update([ + 'start_date' => $request->start_date, + 'end_date' => $request->end_date, + ]); + return response()->json('Event updated'); + // TODO: If the start end times changed, it will be better to send the users an email + // saying the time is changed (remind Google Calender events !) + + if (($result && (count($bookings1) == 1)) || (!$result && (count($bookings1) == 0))) { + $booking->update([ + 'start_date' => $request->start_date, + 'end_date' => $request->end_date, + ]); + + return response()->json('Event updated'); + } else { + // Print message + return response()->json([ + 'error' => 'Unable to locate the event', + ], 404); + } + } + + public function destroy($id) + { + $booking = Reservation::find($id); + + if (!$booking) { + return response()->json([ + 'error' => 'Unable to locate the event', + ], 404); + } + + $booking->delete(); + + return $id; + } +} diff --git a/app/Http/Controllers/Frontend/ComponentView.php b/app/Http/Controllers/Frontend/ComponentView.php old mode 100644 new mode 100755 index d26989ba..fb97c030 --- a/app/Http/Controllers/Frontend/ComponentView.php +++ b/app/Http/Controllers/Frontend/ComponentView.php @@ -16,16 +16,29 @@ public function index() return view('frontend.component.index', compact('componentType')); } + // All Components + public function index_all() + { + $items = ComponentItem::paginate(36); + return view('frontend.component.all', compact('items')); + } + // component Category Page public function viewCategory(ComponentType $componentType) { - $items = $componentType->hasMany(ComponentItem::class)->paginate(12);; + $items = $componentType->hasMany(ComponentItem::class)->paginate(36);; return view('frontend.component.category', compact('items', 'componentType')); } // component Item Page public function viewItem(ComponentItem $componentItem) { - return view('frontend.component.item', compact('componentItem')); + $locationCount = $this->getNumberOfLocationsForItem($componentItem); + $locationStringArray = array(); + for ($i = 0; $i < $locationCount; $i++) { + $locationStringArray[] = $this->getFullLocationPathAsString($componentItem, $i); + } + + return view('frontend.component.item', compact('componentItem', 'locationCount', 'locationStringArray')); } } \ No newline at end of file diff --git a/app/Http/Controllers/Frontend/ConsumableView.php b/app/Http/Controllers/Frontend/ConsumableView.php new file mode 100755 index 00000000..0d0f651c --- /dev/null +++ b/app/Http/Controllers/Frontend/ConsumableView.php @@ -0,0 +1,44 @@ +hasMany(ConsumableItem::class)->paginate(24);; + return view('frontend.consumable.category', compact('items', 'consumableType')); + } + + // conusmable Item Page + public function viewItem(ConsumableItem $consumableItem) + { + $locationCount = $this->getNumberOfLocationsForItem($consumableItem); + $locationStringArray = array(); + for ($i = 0; $i < $locationCount; $i++) { + $locationStringArray[] = $this->getFullLocationPathAsString($consumableItem, $i); + } + + return view('frontend.consumable.item', compact('consumableItem','locationStringArray','locationCount')); + } +} diff --git a/app/Http/Controllers/Frontend/EquipmentView.php b/app/Http/Controllers/Frontend/EquipmentView.php old mode 100644 new mode 100755 index ea6a2ba8..c227702a --- a/app/Http/Controllers/Frontend/EquipmentView.php +++ b/app/Http/Controllers/Frontend/EquipmentView.php @@ -16,17 +16,29 @@ public function index() return view('frontend.equipment.index', compact('eqTypes')); } + // All Equipments + public function index_all() + { + $items = EquipmentItem::paginate(36); + return view('frontend.equipment.all', compact('items')); + } + // Equipment Category Page public function viewCategory(EquipmentType $equipmentType) { - $items = $equipmentType->hasMany(EquipmentItem::class)->paginate(12);; - // ->paginate(16); + $items = $equipmentType->hasMany(EquipmentItem::class)->paginate(36);; return view('frontend.equipment.category', compact('items', 'equipmentType')); } // Equipment Item Page public function viewItem(EquipmentItem $equipmentItem) { - return view('frontend.equipment.item', compact('equipmentItem')); + $locationCount = $this->getNumberOfLocationsForItem($equipmentItem); + $locationStringArray = array(); + for ($i = 0; $i < $locationCount; $i++) { + $locationStringArray[] = $this->getFullLocationPathAsString($equipmentItem, $i); + } + + return view('frontend.equipment.item', compact('equipmentItem','locationStringArray','locationCount')); } -} +} diff --git a/app/Http/Controllers/Frontend/HomeController.php b/app/Http/Controllers/Frontend/HomeController.php old mode 100644 new mode 100755 diff --git a/app/Http/Controllers/Frontend/SearchController.php b/app/Http/Controllers/Frontend/SearchController.php new file mode 100755 index 00000000..a019dc13 --- /dev/null +++ b/app/Http/Controllers/Frontend/SearchController.php @@ -0,0 +1,39 @@ +input('keywords'); + + if (strlen($keywords) == 0) { + return view('frontend.index')->with('status', 'Search string is empty. Please type something'); + } + + $searchResults = (new Search()) + ->registerModel(ComponentItem::class, ['title', 'brand']) + ->registerModel(EquipmentItem::class, ['title', 'brand']) + ->registerModel(Machines::class, ['title']) + ->registerModel(ConsumableItem::class, ['title']) + ->registerModel(RawMaterials::class, ['title', 'description']) + ->search($keywords); + + //create a view to show results on frontend and add the view below + return view('frontend.search.results', compact('searchResults', 'keywords')); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Frontend/StationController.php b/app/Http/Controllers/Frontend/StationController.php new file mode 100755 index 00000000..d64db7ca --- /dev/null +++ b/app/Http/Controllers/Frontend/StationController.php @@ -0,0 +1,66 @@ +id)->where('start_date', '>', Carbon::now()->subDays(8))->get(); + + $color = null; + + foreach ($bookings as $booking) { + + $userVar = User::find($booking->user_id); + $events[] = [ + 'id' => $booking->id, + 'title' => 'Reservation made by ' . $userVar->email . ' for ' . $booking->E_numbers, + 'start' => $booking->start_date, + 'end' => $booking->end_date, + 'stationId' => $stations->id, + 'auth' => $booking->user_id, + 'color' => $color, + ]; + } + + + return view('frontend.stations.station', compact('stations', 'events')); + } + + +} diff --git a/app/Http/Controllers/Frontend/TermsController.php b/app/Http/Controllers/Frontend/TermsController.php old mode 100644 new mode 100755 diff --git a/app/Http/Controllers/Frontend/User/AccountController.php b/app/Http/Controllers/Frontend/User/AccountController.php old mode 100644 new mode 100755 diff --git a/app/Http/Controllers/Frontend/User/CartController.php b/app/Http/Controllers/Frontend/User/CartController.php new file mode 100755 index 00000000..501078c9 --- /dev/null +++ b/app/Http/Controllers/Frontend/User/CartController.php @@ -0,0 +1,105 @@ +get('cart', []); + + if (isset($cart[$id])) { + $cart[$id]['quantity']++; + } else { + $cart[$id] = [ + "name" => $componentItem->title, + "quantity" => 1, + "code" => $componentItem->id, + "image" => $componentItem->image + ]; + } + + session()->put('cart', $cart); + return redirect()->back()->with('success', 'Product added to cart successfully!'); + } + + public function update(Request $request) + { + if ($request->id && $request->quantity) { + $cart = session()->get('cart'); + $cart[$request->id]["quantity"] = $request->quantity; + session()->put('cart', $cart); + session()->flash('success', 'Cart updated successfully'); + } + } + + public function remove(Request $request) + { + if ($request->id) { + $cart = session()->get('cart'); + if (isset($cart[$request->id])) { + unset($cart[$request->id]); + session()->put('cart', $cart); + } + session()->flash('success', 'Product removed successfully'); + } + } + + public function placeOrder(Request $request) + { + $web = request()->validate([ + 'product' => 'required|array|min:1', // TODO: Validate properly + 'quantity' => 'required|array|min:1' + ]); + + $data['ordered_date'] = Carbon::now()->format('Y-m-d'); + $data['user_id'] = $request->user()->id; + $order = new Order($data); + $order->save(); + + for ($i = 0; $i < count($web['product']); $i++) { + $order->componentItems()->attach($web['product'][$i], array('quantity' => $request->quantity[$i])); + } + + // $user_id=$request->user()->id; + // $order_date=$data['ordered_date']; + $orders=Order::where('id',$request->user()->id)->get(); + // return Order::where('id',$request->user()->id)->get();; + return view('frontend.orders.index', compact('orders')); + return response()->json($order,200); + } + +} + diff --git a/app/Http/Controllers/Frontend/User/DashboardController.php b/app/Http/Controllers/Frontend/User/DashboardController.php old mode 100644 new mode 100755 index b58b9c6f..8aa6b3c9 --- a/app/Http/Controllers/Frontend/User/DashboardController.php +++ b/app/Http/Controllers/Frontend/User/DashboardController.php @@ -12,6 +12,6 @@ class DashboardController */ public function index() { - return view('frontend.user.dashboard'); + return view('frontend.user.overview'); } } diff --git a/app/Http/Controllers/Frontend/User/ProfileController.php b/app/Http/Controllers/Frontend/User/ProfileController.php old mode 100644 new mode 100755 diff --git a/app/Http/Controllers/LocaleController.php b/app/Http/Controllers/LocaleController.php old mode 100644 new mode 100755 diff --git a/app/Http/Controllers/LocationAPI.php b/app/Http/Controllers/LocationAPI.php new file mode 100755 index 00000000..7efec291 --- /dev/null +++ b/app/Http/Controllers/LocationAPI.php @@ -0,0 +1,41 @@ + $value) { +// foreach in locations to get the full location path + $full_location_path_array = $this->getFullLocationPathByLocationID($value->location_id); + $locations[$key]->full_location_path = implode(' > ', array_reverse($full_location_path_array)); + +// get item + $item_model = $value->get_item(); + if ($item_model != null) { + $locations[$key]->model = $value->get_item(); + +// item class name for identifying if its equipment, consumable etc... + $full_class_name = get_class($item_model); + $class_name = substr($full_class_name, strrpos($full_class_name, '\\') + 1); + $locations[$key]->item_class_name = $class_name; + + } else { +// the seeder is not consistent with other details. ItemLocations table has records that the equipment table doesn't have + unset($locations[$key]); + } + + + } + $time_end = microtime(true); + $execution_time = ($time_end - $time_start); + $locations['timeToCompute'] = $execution_time; + return $locations; + } +} diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php old mode 100644 new mode 100755 index 87fc614f..7920249b --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -3,6 +3,7 @@ namespace App\Http; use Illuminate\Foundation\Http\Kernel as HttpKernel; +use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful; /** * Class Kernel. @@ -45,11 +46,14 @@ class Kernel extends HttpKernel ], 'api' => [ + EnsureFrontendRequestsAreStateful::class, 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, + \App\Http\Middleware\EncryptCookies::class, // <------- ADD THIS + \Illuminate\Session\Middleware\StartSession::class, // <------ ADD THIS ], - 'admin' => [ + 'admin' => [ /* * This is configurable, disable boilerplate.access.user.admin_requires_2fa instead of removing this */ @@ -58,6 +62,15 @@ class Kernel extends HttpKernel 'password.expires', 'is_admin', ], + + 'user' => [ + /* + * A prefix for all registered users + */ + 'is_admin', + 'is_super_admin', + 'is_user', + ], ]; /** @@ -78,6 +91,7 @@ class Kernel extends HttpKernel 'is_admin' => \App\Domains\Auth\Http\Middleware\AdminCheck::class, 'is_super_admin' => \App\Domains\Auth\Http\Middleware\SuperAdminCheck::class, 'is_user' => \App\Domains\Auth\Http\Middleware\UserCheck::class, + 'editAccess' => \App\Domains\Auth\Http\Middleware\EditabilityCheck::class, 'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class, 'password.expires' => \App\Domains\Auth\Http\Middleware\PasswordExpires::class, 'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class, @@ -104,4 +118,4 @@ class Kernel extends HttpKernel \Illuminate\Routing\Middleware\SubstituteBindings::class, \Illuminate\Auth\Middleware\Authorize::class, ]; -} +} \ No newline at end of file diff --git a/app/Http/Livewire/Backend/AnnouncementTable.php b/app/Http/Livewire/Backend/AnnouncementTable.php new file mode 100755 index 00000000..d2e5baa8 --- /dev/null +++ b/app/Http/Livewire/Backend/AnnouncementTable.php @@ -0,0 +1,69 @@ +sortable(), + Column::make("Type", "type") + ->sortable(), + Column::make("Message", "message") + ->searchable(), + Column::make("Enabled", "enabled") + ->searchable(), + Column::make("Start", "starts_at") + ->sortable(), + Column::make("End", "ends_at") + ->sortable(), + Column::make("Actions") + ]; + } + + public function query(): Builder + { + return Announcement::query() + ->when($this->getFilter('area'), fn ($query, $status) => $query->where('area', $status)) + ->when($this->getFilter('type'), fn ($query, $type) => $query->where('type', $type)); + } + + public function filters(): array + { + $type = ["" => "Any"]; + foreach (Announcement::types() as $key => $value) { + $type[$key] = $value; + } + $area = ["" => "Any"]; + foreach (Announcement::areas() as $key => $value) { + $area[$key] = $value; + } + + return [ + 'area' => Filter::make('Display Area') + ->select($area), + 'type' => Filter::make('Type') + ->select($type), + ]; + } + + public function rowView(): string + { + return 'backend.announcements.index-table-row'; + } +} diff --git a/app/Http/Livewire/Backend/ComponentItemTable.php b/app/Http/Livewire/Backend/ComponentItemTable.php new file mode 100755 index 00000000..80c7fb10 --- /dev/null +++ b/app/Http/Livewire/Backend/ComponentItemTable.php @@ -0,0 +1,62 @@ +sortable(), + Column::make("Title", "title") + ->sortable() + ->searchable(), + Column::make("Product Code and Brand"), + Column::make("Category") + ->sortable() + ->searchable(), + Column::make("Actions") + ]; + } + + public function query(): Builder + { + return ComponentItem::query() + ->when($this->getFilter('category'), fn ($query, $category) => $query->where('component_type_id', $category));; + } + + public function filters(): array + { + // Category ------------------------------------------------------ + $categoriesFromDB = ComponentType::pluck('title', 'id')->toArray(); + + // Add '' => "Any" to the beginning of the array + $categories = array(); + $categories[''] = "Any"; + foreach ($categoriesFromDB as $key => $value) { + $categories[$key] = $value; + } + + + return [ + 'category' => Filter::make('Category') + ->select($categories) + ]; + } + + public function rowView(): string + { + return 'backend.component.items.index-table-row'; + } +} \ No newline at end of file diff --git a/app/Http/Livewire/Backend/ComponentTypeTable.php b/app/Http/Livewire/Backend/ComponentTypeTable.php new file mode 100755 index 00000000..35731853 --- /dev/null +++ b/app/Http/Livewire/Backend/ComponentTypeTable.php @@ -0,0 +1,36 @@ +sortable(), + Column::make("Title", "title") + ->sortable() + ->searchable(), + Column::make("Parent Category", 'parent_id'), + Column::make("Description", "description"), + Column::make("Actions"), + ]; + } + + public function query(): Builder + { + return ComponentType::query(); + } + + public function rowView(): string + { + return 'backend.component.types.index-table-row'; + } +} diff --git a/app/Http/Livewire/Backend/ConsumableItemTable.php b/app/Http/Livewire/Backend/ConsumableItemTable.php new file mode 100755 index 00000000..595483cc --- /dev/null +++ b/app/Http/Livewire/Backend/ConsumableItemTable.php @@ -0,0 +1,63 @@ +sortable(), + Column::make("Title", "title") + ->sortable() + ->searchable(), + Column::make("Category", "consumable_type_id"), + Column::make("Form Factor", "formFactor"), + Column::make("Quantity", "quantity"), + Column::make("Actions"), + ]; + } + + public function query(): Builder + { + return ConsumableItem::query() + ->when($this->getFilter('category'), fn($query, $category) => $query->where('consumable_type_id', $category)); + ; + } + + public function filters(): array + { + // Category ------------------------------------------------------ + $categoriesFromDB = ConsumableType::pluck('title','id')->toArray(); + + // Add '' => "Any" to the beginning of the array + $categories = array(); + $categories[''] = "Any"; + foreach ($categoriesFromDB as $key => $value) { + $categories[$key] = $value; + } + + + return [ + 'category' => Filter::make('Category') + ->select($categories) + ]; + } + + public function rowView(): string + { + return 'backend.consumable.items.index-table-row'; + } + +} diff --git a/app/Http/Livewire/Backend/ConsumableTypeTable.php b/app/Http/Livewire/Backend/ConsumableTypeTable.php new file mode 100755 index 00000000..388c4e8b --- /dev/null +++ b/app/Http/Livewire/Backend/ConsumableTypeTable.php @@ -0,0 +1,36 @@ +sortable(), + Column::make("Title",'title') + ->sortable() + ->searchable(), + Column::make("Parent Category",'parent_id'), + Column::make("Description",'description'), + Column::make("Actions") + ]; + } + + public function query(): Builder + { + return ConsumableType::query(); + } + + public function rowView(): string + { + return 'backend.consumable.types.index-table-row'; + } +} diff --git a/app/Http/Livewire/Backend/EquipmentItemTable.php b/app/Http/Livewire/Backend/EquipmentItemTable.php new file mode 100755 index 00000000..400c4110 --- /dev/null +++ b/app/Http/Livewire/Backend/EquipmentItemTable.php @@ -0,0 +1,82 @@ +sortable(), + Column::make("Title", 'title') + ->sortable() + ->searchable(), + Column::make("Product Code"), + Column::make("Quantity", 'quantity') + ->sortable(), + Column::make("Category", 'equipment_type_id') + ->sortable(), + Column::make("Price (LKR)", 'price') + ->sortable(), + // Column::make("Dimensions (WxLxH cm)"), + // Column::make("Weight (g)", "weight") + // ->sortable(), + Column::make("Actions") + ]; + } + + public function query(): Builder + { + return EquipmentItem::query() + ->when($this->getFilter('category'), fn($query, $category) => $query->where('equipment_type_id', $category)); + } + + public function filters(): array + { + // Category ------------------------------------------------------ + $categoriesFromDB = EquipmentType::pluck('title', 'id')->toArray(); + + // Add '' => "Any" to the beginning of the array + $categories = [''=> "Any"]; + $cat = EquipmentType::where('parent_id', NULL)->get(); + + // For now, only support upto 3 levels + foreach ($cat as $key => $value) { + $categories[$value->id] = $value->title; + // Level 2 + if ($value->children()->count() > 0) { + foreach ($value->children() as $l) { + $categories[$l->id] = $l->getFullEquipmentType(); + // Level 3 + if ($l->children()->count() > 0) { + foreach ($l->children() as $ll) { + $categories[$ll->id] = $ll->getFullEquipmentType(); + } + } + } + } + } + + return [ + 'category' => Filter::make('Category') + ->select($categories) + ]; + } + + public function rowView(): string + { + return 'backend.equipment.items.index-table-row'; + } + +} \ No newline at end of file diff --git a/app/Http/Livewire/Backend/EquipmentTypeTable.php b/app/Http/Livewire/Backend/EquipmentTypeTable.php new file mode 100755 index 00000000..e617679b --- /dev/null +++ b/app/Http/Livewire/Backend/EquipmentTypeTable.php @@ -0,0 +1,36 @@ +sortable(), + Column::make("Title", "title") + ->sortable() + ->searchable(), + Column::make("Parent Category", 'parent_id'), + Column::make("Description", "description"), + Column::make("Actions"), + ]; + } + + public function query(): Builder + { + return EquipmentType::query(); + } + + public function rowView(): string + { + return 'backend.equipment.types.index-table-row'; + } +} diff --git a/app/Http/Livewire/Backend/FabricationsSupervisorPendingFabricationTable.php b/app/Http/Livewire/Backend/FabricationsSupervisorPendingFabricationTable.php new file mode 100755 index 00000000..0cc08683 --- /dev/null +++ b/app/Http/Livewire/Backend/FabricationsSupervisorPendingFabricationTable.php @@ -0,0 +1,42 @@ +sortable(), + Column::make("Status", "status") + ->sortable() + ->searchable(), + Column::make("Machine", "machine") + ->sortable(), + Column::make("Material", "material") + ->sortable(), + Column::make("Student", "student") + ->sortable(), + ]; + } + + public function query(): Builder + { + return JobRequests::query() + ->where('supervisor', \Auth::user()->id) + ->where("status",'PENDING_FABRICATION') + ->orderByDesc('id'); + } + + public function rowView(): string + { + return 'backend.jobs.supervisor.pending-fabrication-table-row'; + } +} diff --git a/app/Http/Livewire/Backend/FabricationsTechOfficerTable.php b/app/Http/Livewire/Backend/FabricationsTechOfficerTable.php new file mode 100755 index 00000000..e13efee4 --- /dev/null +++ b/app/Http/Livewire/Backend/FabricationsTechOfficerTable.php @@ -0,0 +1,46 @@ +sortable(), + Column::make("Status", "status") + ->sortable() + ->searchable(), + Column::make("Machine", "machine") + ->sortable(), + Column::make("Material", "material") + ->sortable(), + Column::make("Supervisor", "supervisor") + ->sortable(), + Column::make("Actions") + ]; + } + + public function query(): Builder + { + return JobRequests::query() + ->where('status', "WAITING_TO_APPROVAL") + // TODO: This needs to checked. Not sure if its working properly. + // This needs to be equal with \App\Models\JobRequests::jobsForTechOfficer() + // Resulting query is this -> select count(*) as aggregate from "job_requests" where "status" = 'WAITING_TO_APPROVAL' or "status" = 'PENDING_FABRICATION' + ->orWhere('status', "PENDING_FABRICATION") + ->orderByDesc('id'); + } + + public function rowView(): string + { + return 'backend.jobs.technical-officer.table-row'; + } +} diff --git a/app/Http/Livewire/Backend/FabricationsUserTable.php b/app/Http/Livewire/Backend/FabricationsUserTable.php new file mode 100755 index 00000000..a5461db3 --- /dev/null +++ b/app/Http/Livewire/Backend/FabricationsUserTable.php @@ -0,0 +1,42 @@ +sortable(), + Column::make("Status", "status") + ->sortable() + ->searchable(), + Column::make("Machine", "machine") + ->sortable(), + Column::make("Material", "material") + ->sortable(), + Column::make("Supervisor", "supervisor") + ->sortable(), + Column::make("Actions") + ]; + } + + public function query(): Builder + { + return JobRequests::query() + ->where('student', \Auth::user()->id) + ->orderByDesc('id'); + } + + public function rowView(): string + { + return 'backend.jobs.student.student-table-row'; + } +} diff --git a/app/Http/Livewire/Backend/FabricationsWaitingForSupervisorApprovalTable.php b/app/Http/Livewire/Backend/FabricationsWaitingForSupervisorApprovalTable.php new file mode 100755 index 00000000..dbf61ab3 --- /dev/null +++ b/app/Http/Livewire/Backend/FabricationsWaitingForSupervisorApprovalTable.php @@ -0,0 +1,43 @@ +sortable(), + Column::make("Status", "status") + ->sortable() + ->searchable(), + Column::make("Machine", "machine") + ->sortable(), + Column::make("Material", "material") + ->sortable(), + Column::make("Student", "student") + ->sortable(), + Column::make("Actions") + ]; + } + + public function query(): Builder + { + return JobRequests::query() + ->where('supervisor', \Auth::user()->id) + ->where("status",'WAITING_SUPERVISOR_APPROVAL') + ->orderByDesc('id'); + } + + public function rowView(): string + { + return 'backend.jobs.supervisor.waiting-for-supervisor-approval-table-row'; + } +} diff --git a/app/Http/Livewire/Backend/LocationsTable.php b/app/Http/Livewire/Backend/LocationsTable.php new file mode 100755 index 00000000..ff1d0c67 --- /dev/null +++ b/app/Http/Livewire/Backend/LocationsTable.php @@ -0,0 +1,55 @@ +sortable(), + Column::make("Location Name", "location") + ->sortable() + ->searchable(), + Column::make("Actions") + + ]; + } + + public function query(): Builder + { + return Locations::query() + ->when($this->getFilter('location'), fn($query, $location) => $query->where('parent_location', $location)); + } + + public function filters(): array + { + // Add '' => "Any" to the beginning of the array + $locations = ["" => "Any"]; + $locationList = Locations::all()->where('parent_location', 1)->all(); + + foreach ($locationList as $key => $value) { + $locations[$value->id] = $value->location; + } + + return [ + 'location' => Filter::make('Location') + ->select($locations), + ]; + } + + public function rowView(): string + { + return 'backend.locations.index-table-row'; + } +} diff --git a/app/Http/Livewire/Backend/LocationsToggler.php b/app/Http/Livewire/Backend/LocationsToggler.php new file mode 100755 index 00000000..0d61af18 --- /dev/null +++ b/app/Http/Livewire/Backend/LocationsToggler.php @@ -0,0 +1,50 @@ +itemModel->inventoryCode())->where('location_id', $this->locationID)->get(); + if ($locations->count() == 0) { + ItemLocations::create([ + 'location_id' => $this->locationID, + 'item_id' => $this->itemModel->inventoryCode() + ]); + } else { + $locations[0]->delete(); + } + $isChecked = true; + } + + // Function to show the X, Y, Z input boxes once the user ticks the checkbox + public function showXYZ() + { + $this->emit('showXYZ'); + } + + + public function mount() + { + } + + public function render() + { + $this->isAvailableInLocation = ItemLocations::where('item_id', $this->itemModel->inventoryCode())->where('location_id', $this->locationID)->exists(); + return view('livewire.locations-toggler', ['id' => $this->locationID, 'location' => $this->locationTitle]); + } +} diff --git a/app/Http/Livewire/Backend/MachinesTable.php b/app/Http/Livewire/Backend/MachinesTable.php new file mode 100755 index 00000000..abb92d98 --- /dev/null +++ b/app/Http/Livewire/Backend/MachinesTable.php @@ -0,0 +1,66 @@ +sortable(), + Column::make("Title", "title") + ->sortable() + ->searchable(), + Column::make("Type", "type") + ->sortable(), + Column::make("Build Capacity (WxLxH)"), + Column::make("Status", "status") + ->sortable(), + Column::make("Lifespan", "lifespan") + ->sortable(), + Column::make("Actions") + ]; + } + + public function query(): Builder + { + return Machines::query() + ->when($this->getFilter('status'), fn($query, $status) => $query->where('status', $status)) + ->when($this->getFilter('type'), fn($query, $type) => $query->where('type', $type)); + } + + public function filters(): array + { + // Add '' => "Any" to the beginning of the array + $status = ["" => "Any"]; + foreach (Machines::availabilityOptions() as $key => $value) { + $status[$key] = $value; + } + + $type = ["" => "Any"]; + foreach (Machines::types() as $key => $value) { + $type[$key] = $value; + } + + return [ + 'status' => Filter::make('Status') + ->select($status), + 'type' => Filter::make('Type') + ->select($type), + ]; + } + + + public function rowView(): string + { + return 'backend.machines.index-table-row'; + } +} diff --git a/app/Http/Livewire/Backend/RawMaterialsTable.php b/app/Http/Livewire/Backend/RawMaterialsTable.php new file mode 100755 index 00000000..ee5b1a40 --- /dev/null +++ b/app/Http/Livewire/Backend/RawMaterialsTable.php @@ -0,0 +1,56 @@ +sortable(), + Column::make("Title", "title") + ->sortable() + ->searchable(), + Column::make("Color", "color") + ->sortable() + ->searchable(), + Column::make("Quantity", "quantity") + ->sortable(), + Column::make("Availability", "availability"), + Column::make("Actions") + ]; + } + + public function query(): Builder + { + return RawMaterials::query() + ->when($this->getFilter('availability'), fn($query, $availability) => $query->where('availability', $availability)); + } + + public function filters(): array + { + // Add '' => "Any" to the beginning of the array + $availabilities = ["" => "Any"]; + foreach (RawMaterials::availabilityOptions() as $key => $value) { + $availabilities[$key] = $value; + } + + return [ + 'availability' => Filter::make('Availability') + ->select($availabilities) + ]; + } + + public function rowView(): string + { + return 'backend.raw_materials.index-table-row'; + } +} diff --git a/app/Http/Livewire/Backend/RolesTable.php b/app/Http/Livewire/Backend/RolesTable.php old mode 100644 new mode 100755 diff --git a/app/Http/Livewire/Backend/StationsTable.php b/app/Http/Livewire/Backend/StationsTable.php new file mode 100755 index 00000000..b98e243d --- /dev/null +++ b/app/Http/Livewire/Backend/StationsTable.php @@ -0,0 +1,36 @@ +sortable(), + Column::make("Station Name", "stationName") + ->sortable() + ->searchable(), + Column::make("Description", "description"), + Column::make("Capacity", "capacity"), + Column::make("Actions") + ]; + } + + public function query(): Builder + { + return Stations::query(); + } + + public function rowView(): string + { + return 'backend.station.index-table-row'; + } +} diff --git a/app/Http/Livewire/Backend/UsersTable.php b/app/Http/Livewire/Backend/UsersTable.php old mode 100644 new mode 100755 index c2bb2cff..7115ba8c --- a/app/Http/Livewire/Backend/UsersTable.php +++ b/app/Http/Livewire/Backend/UsersTable.php @@ -75,6 +75,9 @@ public function filters(): array '' => 'Any', User::TYPE_ADMIN => 'Administrators', User::TYPE_USER => 'Users', + User::TYPE_LECTURER => 'Lecturers', + User::TYPE_TECH_OFFICER => 'Technical Officers', + User::TYPE_MAINTAINER => 'Maintainers', ]), 'active' => Filter::make('Active') ->select([ @@ -97,8 +100,8 @@ public function filters(): array public function columns(): array { return [ - Column::make(__('Type'))->sortable(), Column::make(__('Name'))->sortable(), + Column::make(__('Type'))->sortable(), Column::make(__('E-mail'), 'email')->sortable(), Column::make(__('Verified'), 'email_verified_at')->sortable(), // Column::make(__('2FA'), 'two_factor_auth_count')->sortable(), diff --git a/app/Http/Livewire/Frontend/TwoFactorAuthentication.php b/app/Http/Livewire/Frontend/TwoFactorAuthentication.php old mode 100644 new mode 100755 index 71dd6ab0..e02a4045 --- a/app/Http/Livewire/Frontend/TwoFactorAuthentication.php +++ b/app/Http/Livewire/Frontend/TwoFactorAuthentication.php @@ -26,7 +26,7 @@ public function validateCode(Request $request) 'code' => 'required|min:6', ]); - if ($request->user()->confirmTwoFactorAuth($this->code)) { + if ($request->user()->confirmTwoFactorAuth($this->code)) { $this->resetErrorBag(); session()->flash('flash_success', __('Two Factor Authentication Successfully Enabled')); @@ -34,9 +34,9 @@ public function validateCode(Request $request) return redirect()->route('frontend.auth.account.2fa.show'); } - $this->addError('code', __('Your authorization code was invalid. Please try again.')); + $this->addError('code', __('Your authorization code was invalid. Please try again.')); - return false; + return false; } /** diff --git a/app/Http/Livewire/LocationsToggler.php b/app/Http/Livewire/LocationsToggler.php new file mode 100755 index 00000000..808ba08d --- /dev/null +++ b/app/Http/Livewire/LocationsToggler.php @@ -0,0 +1,41 @@ +itemModel->inventoryCode())->where('location_id', $this->locationID)->get(); + if ($locations->count() == 0) { + ItemLocations::create([ + 'location_id' => $this->locationID, + 'item_id' => $this->itemModel->inventoryCode() + ]); + } else { + $locations[0]->delete(); + } + } + + public function mount() + { + } + + public function render() + { + $this->isAvailableInLocation = ItemLocations::where('item_id', $this->itemModel->inventoryCode())->where('location_id', $this->locationID)->exists(); + return view('livewire.locations-toggler' , ['id'=> $this->locationID, 'location' => $this->locationTitle]); + } +} diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php old mode 100644 new mode 100755 diff --git a/app/Http/Middleware/CheckForMaintenanceMode.php b/app/Http/Middleware/CheckForMaintenanceMode.php old mode 100644 new mode 100755 diff --git a/app/Http/Middleware/EncryptCookies.php b/app/Http/Middleware/EncryptCookies.php old mode 100644 new mode 100755 diff --git a/app/Http/Middleware/LocaleMiddleware.php b/app/Http/Middleware/LocaleMiddleware.php old mode 100644 new mode 100755 diff --git a/app/Http/Middleware/RedirectIfAuthenticated.php b/app/Http/Middleware/RedirectIfAuthenticated.php old mode 100644 new mode 100755 diff --git a/app/Http/Middleware/TrimStrings.php b/app/Http/Middleware/TrimStrings.php old mode 100644 new mode 100755 diff --git a/app/Http/Middleware/TrustHosts.php b/app/Http/Middleware/TrustHosts.php old mode 100644 new mode 100755 diff --git a/app/Http/Middleware/TrustProxies.php b/app/Http/Middleware/TrustProxies.php old mode 100644 new mode 100755 diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php old mode 100644 new mode 100755 diff --git a/app/Http/Requests/Frontend/User/UpdateProfileRequest.php b/app/Http/Requests/Frontend/User/UpdateProfileRequest.php old mode 100644 new mode 100755 diff --git a/app/Mail/ReservationReminder.php b/app/Mail/ReservationReminder.php new file mode 100755 index 00000000..cded7c24 --- /dev/null +++ b/app/Mail/ReservationReminder.php @@ -0,0 +1,41 @@ +booking=$booking; + $this->station=$station; + } + + /** + * Build the message. + * + * @return $this + */ + public function build() + { + return $this->markdown('emails.reservation.reservationreminder') + ->subject('Image of station after use'); + } +} diff --git a/app/Mail/StationReservationMail.php b/app/Mail/StationReservationMail.php new file mode 100755 index 00000000..828a8fa6 --- /dev/null +++ b/app/Mail/StationReservationMail.php @@ -0,0 +1,47 @@ +reserver=$reserver; + $this->station=$station; + $this->booking=$booking; + } + + /** + * Build the message. + * + * @return $this + */ + public function build() + { + + return $this->markdown('emails.reservation.reservationmade') + ->subject('MakerSpace Lab Reservation'); + + } +} diff --git a/app/Models/Cart.php b/app/Models/Cart.php new file mode 100755 index 00000000..964ff27e --- /dev/null +++ b/app/Models/Cart.php @@ -0,0 +1,15 @@ +component_type_id != null) return $this->belongsTo(ComponentType::class, 'component_type_id', 'id'); - return null; + // do not change. Relationships are defined this way. do not return null. causes errors in livewire that are untraceable. + return $this->belongsTo(ComponentType::class, 'component_type_id', 'id'); } + // reverse search depends on this. Change SearchController.php if you're changing this public function inventoryCode() { return $this->component_type->inventoryCode() . "/" . $this->id; @@ -27,7 +30,22 @@ public function inventoryCode() public function thumbURL() { if ($this->thumb != null) return '/img/component_items/' . $this->thumb; - return null; + else return $this->component_type->thumbURL(); } + // used to search + public function getSearchResult(): SearchResult + { + $url = route('admin.component.items.show', $this); + return new SearchResult( + $this, + $this->title, + $url + ); + } + + public function orders() + { + return $this->belongsToMany(Order::class); + } } diff --git a/app/Models/ComponentItemOrder.php b/app/Models/ComponentItemOrder.php new file mode 100755 index 00000000..c1ae98d1 --- /dev/null +++ b/app/Models/ComponentItemOrder.php @@ -0,0 +1,14 @@ +id; + return sprintf("CM/%02d", $this->id); } // Return the relative URL of the thumbnail public function thumbURL() { if ($this->thumb != null) return '/img/component_types/' . $this->thumb; - return null; + else if ($this->parent()->first() != null) { + return $this->parent()->first()->thumbURL(); + } else { + return config('constants.frontend.dummy_thumb'); + } } // Return the parent item of the current type or null public function parent() { - if ($this->parent_id !== null) return ComponentType::find($this->parent_id); - return null; + return $this->hasOne(ComponentType::class, "id", "parent_id"); } // Return the children item types of this item type @@ -40,6 +43,27 @@ public function children() // Return the items listed under this item type public function getItems() { - return $this->hasMany(EquipmentItem::class)->get(); + return $this->hasMany(ComponentItem::class)->get(); + } + + public function getFullComponentType() + { + $item = $this; + $title = $item->title; + while (!($item->parent()->first() == NULL)) { + $item = $item->parent()->first(); + $title = $item->title . " > " . $title; + } + return $title; + } + + public static function getFullTypeList() + { + $typeList = ComponentType::all(); + $types = array(); + foreach ($typeList as $type) { + $types[$type->id] = $type->getFullComponentType(); + } + return $types; } } diff --git a/app/Models/ConsumableItem.php b/app/Models/ConsumableItem.php new file mode 100755 index 00000000..1b854e2c --- /dev/null +++ b/app/Models/ConsumableItem.php @@ -0,0 +1,45 @@ +belongsTo(ConsumableType::class, 'consumable_type_id', 'id'); + } + + // reverse search depends on this. Change SearchController.php if you're changing this + public function inventoryCode() + { + return $this->consumable_type->inventoryCode() . "/" . $this->id; + } + + // Return the relative URL of the thumbnail + public function thumbURL() + { + if ($this->thumb != null) return '/img/consumable_items/' . $this->thumb; + else return $this->consumable_type->thumbURL(); + } + + public function getSearchResult(): SearchResult + { + $url = route('admin.consumable.items.show', $this); + return new SearchResult( + $this, + $this->title, + $url + ); + } +} diff --git a/app/Models/ConsumableType.php b/app/Models/ConsumableType.php new file mode 100755 index 00000000..ac4d9d48 --- /dev/null +++ b/app/Models/ConsumableType.php @@ -0,0 +1,75 @@ +id; + } + + // Return the relative URL of the thumbnail + public function thumbURL() + { + if ($this->thumb != null) return '/img/consumable_types/' . $this->thumb; + else if ($this->parent()->first() != null) { + return $this->parent()->first()->thumbURL(); + } else { + return config('constants.frontend.dummy_thumb'); + } + } + + // Return the parent item of the current type or null + public function parent() + { + return $this->hasOne(ConsumableType::class, "id", "parent_id"); + } + + // Return the children item types of this item type + public function children() + { + return ConsumableType::where('parent_id', $this->id)->get(); + } + + // Return the items listed under this item type + public function getItems() + { + return $this->hasMany(ConsumableType::class)->get(); + } + + public function getFullConsumableType() + { + $item = $this; + $title = $item->title; + while (!($item->parent()->first() == NULL)) { + $item = $item->parent()->first(); + $title = $item->title . " > " . $title; + } + return $title; + } + + public static function getFullTypeList() + { + $typeList = ConsumableType::all(); + $types = array(); + foreach ($typeList as $type) { + $types[$type->id] = $type->getFullConsumableType(); + } + return $types; + } +} diff --git a/app/Models/EquipmentItem.php b/app/Models/EquipmentItem.php old mode 100644 new mode 100755 index 1791c668..000ffdb0 --- a/app/Models/EquipmentItem.php +++ b/app/Models/EquipmentItem.php @@ -2,10 +2,12 @@ namespace App\Models; -use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Spatie\Searchable\Searchable; +use Spatie\Searchable\SearchResult; +use Illuminate\Database\Eloquent\Factories\HasFactory; -class EquipmentItem extends Model +class EquipmentItem extends Model implements Searchable { use HasFactory; @@ -14,10 +16,11 @@ class EquipmentItem extends Model // Link the Equipment Type table public function equipment_type() { - if ($this->equipment_type_id != null) return $this->belongsTo(EquipmentType::class, 'equipment_type_id', 'id'); - return null; + // Do not change. + return $this->belongsTo(EquipmentType::class, 'equipment_type_id', 'id'); } + // reverse search depends on this. Change SearchController.php if you're changing this public function inventoryCode() { return $this->equipment_type->inventoryCode() . "/" . $this->id; @@ -27,7 +30,16 @@ public function inventoryCode() public function thumbURL() { if ($this->thumb != null) return '/img/equipment_items/' . $this->thumb; - return null; + else return $this->equipment_type->thumbURL(); } + public function getSearchResult(): SearchResult + { + $url = route('admin.equipment.items.show', $this); + return new SearchResult( + $this, + $this->title, + $url + ); + } } diff --git a/app/Models/EquipmentType.php b/app/Models/EquipmentType.php old mode 100644 new mode 100755 index 3a73f0d7..53608f65 --- a/app/Models/EquipmentType.php +++ b/app/Models/EquipmentType.php @@ -12,32 +12,63 @@ class EquipmentType extends Model protected $guarded = []; // A Unique ID assigned by the inventory management system + // reverse search depends on this. Change SearchController.php if you're changing this public function inventoryCode() { - // TODO: Make a common standard for this - return "MS/EQ/" . $this->id; + return sprintf("EQ/%02d", $this->id); } // Return the relative URL of the thumbnail public function thumbURL() { if ($this->thumb != null) return '/img/equipment_types/' . $this->thumb; - return null; + else if ($this->parent()->first() != null) { + return $this->parent()->first()->thumbURL(); + } else { + return config('constants.frontend.dummy_thumb'); + } } - // Return the parent item of the current type or null - public function parent() + // Return the parent item id + public function parent_id() { if ($this->parent_id !== null) return EquipmentType::find($this->parent_id); return null; } + // Return the parent item + public function parent() + { + return $this->hasOne(EquipmentType::class, "id", "parent_id"); + } + // Return the children item types of this item type public function children() { return EquipmentType::where('parent_id', $this->id)->get(); } + public static function getFullTypeList() + { + $typeList = EquipmentType::all(); + $types = array(); + foreach ($typeList as $type) { + $types[$type->id] = $type->getFullEquipmentType(); + } + return $types; + } + + public function getFullEquipmentType() + { + $item = $this; + $fullTitle = $this->title; + while (!($item->parent()->first() == NULL || $item->parent()->first()->id == NULL)) { + $item = $item->parent()->first(); + $fullTitle = $item->title . " > " . $fullTitle; + } + return $fullTitle; + } + // Return the items listed under this item type public function getItems() { diff --git a/app/Models/ItemLocations.php b/app/Models/ItemLocations.php new file mode 100755 index 00000000..ed052942 --- /dev/null +++ b/app/Models/ItemLocations.php @@ -0,0 +1,52 @@ +hasOne(Locations::class, "id"); + } + + public function get_item() + { + $item_to_return = null; + $item_id = $this->item_id; + $exploded = explode("/", $item_id); + if ($exploded[0] == "EQ") { + $get_from_db = EquipmentItem::where('id', end($exploded))->get(); + if (count($get_from_db) > 0) { + $item_to_return = $get_from_db[0]; + } + } elseif ($exploded[0] == "MC") { + $get_from_db = Machines::where('id', end($exploded))->get(); + if (count($get_from_db) > 0) { + $item_to_return = $get_from_db[0]; + } + } elseif ($exploded[0] == "CS") { + $get_from_db = ConsumableItem::where('id', end($exploded))->get(); + if (count($get_from_db) > 0) { + $item_to_return = $get_from_db[0]; + } + } elseif ($exploded[0] == "RM") { + $get_from_db = RawMaterials::where('id', (int)end($exploded))->get(); + if (count($get_from_db) > 0) { + $item_to_return = $get_from_db[0]; + } + } elseif ($exploded[0] == "CM") { + $get_from_db = ComponentItem::where('id', end($exploded))->get(); + if (count($get_from_db) > 0) { + $item_to_return = $get_from_db[0]; + } + } + return $item_to_return; + } +} diff --git a/app/Models/JobRequests.php b/app/Models/JobRequests.php new file mode 100755 index 00000000..795fb408 --- /dev/null +++ b/app/Models/JobRequests.php @@ -0,0 +1,84 @@ + 'Pending', + 'WAITING_SUPERVISOR_APPROVAL' => 'Waiting for Supervisor Approval', + 'WAITING_TO_APPROVAL' => 'Waiting for Approval', + // 'ON_REVISION' => 'On Revision', + 'PENDING_FABRICATION' => 'Pending Fabrication', + 'COMPLETED' => 'Completed', + 'NOT_APPROVED' => 'Not Approved' + ]; + } + + + public function machine_info() + { + if ($this->machine != null) return $this->belongsTo(Machines::class, 'machine', 'id'); + return null; + } + + public function material_info() + { + if ($this->machine != null) return $this->belongsTo(RawMaterials::class, 'material', 'id'); + return null; + } + + public function supervisor_info() + { + if ($this->supervisor != null) return $this->belongsTo(User::class, 'supervisor', 'id'); + return null; + } + + public function student_info() + { + if ($this->student != null) return $this->belongsTo(User::class, 'student', 'id'); + return null; + } + + public static function jobsForTechOfficer() + { + // The same thing is written at app/Http/Livewire/Backend/FabricationsTechOfficerTable.php in querybuilder function. + // Change that too if youre changing this. + + // Waiting for approval + $jobs_approval = JobRequests::where('status', 'WAITING_TO_APPROVAL')->get(); + + // Pending fabrication + $jobs_pending = JobRequests::where('status', 'PENDING_FABRICATION')->get(); + + // Completed + // $jobs_completed = JobRequests::where('status', 'COMPLETED')->get(); + + return $jobs_approval->merge($jobs_pending); + } + + // Return the relative URL of the thumbnail + public function thumbURL() + { + if ($this->thumb != null) return '/img/jobs/' . $this->thumb; + return null; + } + + // Return the relative URL of the thumbnail + public function fileURL() + { + if ($this->file != null) return '/files/jobs/' . $this->file; + return null; + } +} diff --git a/app/Models/Locations.php b/app/Models/Locations.php new file mode 100755 index 00000000..184b318f --- /dev/null +++ b/app/Models/Locations.php @@ -0,0 +1,53 @@ +hasOne(Locations::class, "id", "parent_location"); + } + + // Get array of all locations in their full path form ( root > child 1 > child 2 > child 3 etc...) + public static function getFullLocationStringFromPluck() + { + $locations = Locations::all(); + + $IDandFullPathArray = array(); + foreach ($locations as $location) { + $IDandFullPathArray[$location->id] = $location->getFullLocationAddress(); + } + + return $IDandFullPathArray; + } + + // Get the location address + public function getFullLocationAddress() + { + $item = $this; + $location = $this->location; + while (!($item->get_parent_location()->first() == NULL || $item->get_parent_location()->first()->id == 1)) { + $item = $item->get_parent_location()->first(); + $location = $item->location . " > " . $location; + } + return $location; + } + + // Get the collection of children of the current location object + public function getChildrenLocations() + { + return Locations::where('parent_location', $this->id)->get(); + } +} diff --git a/app/Models/Machines.php b/app/Models/Machines.php new file mode 100755 index 00000000..11a3dc39 --- /dev/null +++ b/app/Models/Machines.php @@ -0,0 +1,123 @@ +id); + } + + // Return the relative URL of the thumbnail + public function thumbURL() + { + if ($this->thumb != null) return '/img/machines/' . $this->thumb; + return null; + } + + // Types of the machines + public static function types() + { + return [ + 'CNC' => 'CNC Milling Machine', + 'FDM_3D_PRINTER' => '3D Printer (FDM)', + 'LASER_CUTTER' => 'Laser Cutter', + 'PCB_MILL' => 'PCB Milling Machine' + ]; + } + + // Machine availability options + public static function availabilityOptions() + { + return [ + 'AVAILABLE' => 'Available', + 'NOT_AVAILABLE' => 'Not Available', + 'CONDITIONALLY_AVAILABLE' => 'Conditionally Available']; + } + + // Lifespan of the machine in hour and minute format + public function lifespanString() + { + return (intdiv($this->lifespan, 60)) . " hours " . ($this->lifespan % 60) . " minutes"; + } + + public function getLocations() + { + return ItemLocations::where('item_id', $this->inventoryCode())->get() || 1; + } + + public function getSearchResult(): SearchResult + { + $url = route('admin.machines.show', $this); + + return new SearchResult( + $this, + $this->title, + $url + ); + } + + //get location + public function getLocation(){ + $locationID = ItemLocations::where('item_id',$this->inventoryCode())->get()->first()->location_id; + if ($locationID == null){ + return null; + } else { + $count = $this->getNumberOfLocationsForItem($this); + $locationStrings = array(); + for ($i=0; $i < $count; $i++) { + $locationStrings[] = $this->getFullLocationPathAsString($this, $i); + } + return $locationStrings; + } + } + + public function getFullLocationPathByLocationID(int $id){ + $locationID = $id; + $locations_array = array(); + while (true) { + $thisLocation = Locations::where('id', $locationID)->get()[0]; + $locations_array[] = $thisLocation->location; + $locationID = $thisLocation->parent_location; + + if ($locationID == null) break; + } + + return $locations_array; + } + + public function getFullLocationPathAsString(Model $item, int $index){ + $location_array = $this->getFullLocationPathAsArray($item,$index); + return implode(' > ', array_reverse($location_array)); + } + + public function getFullLocationPathAsArray(Model $item, int $index) + { + $locations_array = array(); +// find the item location id from the item_locations table + $locationID = ItemLocations::where('item_id', $item->inventoryCode())->get(); + if ($locationID->count() > 0) { + $locationID = $locationID[$index]->location_id; + } else { + return $locations_array; + } + return $this->getFullLocationPathByLocationID($locationID); + } + + public function getNumberOfLocationsForItem(Model $item){ + $locationID = ItemLocations::where('item_id', $item->inventoryCode())->get(); + return $locationID->count(); + } + +} diff --git a/app/Models/Order.php b/app/Models/Order.php new file mode 100755 index 00000000..2e27bf01 --- /dev/null +++ b/app/Models/Order.php @@ -0,0 +1,43 @@ +belongsToMany(ComponentItem::class)->withPivot('quantity'); + } + + public function user() + { + return $this->belongsTo(User::class); + } + + + public function dueDays() + { + $now = Carbon::now()->format('Y-m-d'); + $end = Carbon::parse($this->due_date_to_return); + return ($end->diffInDays($now)); + } + + public function generateOtp(){ + $otp = rand(1000,9999); + $this->otp = $otp; + $this->save(); + return $otp; + } + + public function checkOtp($otp){ + return $otp==$this->otp; + } +} diff --git a/app/Models/RawMaterials.php b/app/Models/RawMaterials.php new file mode 100755 index 00000000..bf43a40f --- /dev/null +++ b/app/Models/RawMaterials.php @@ -0,0 +1,100 @@ +id); + } + + // Return the relative URL of the thumbnail + public function thumbURL() + { + if ($this->thumb != null) return '/img/raw_materials/' . $this->thumb; + return null; + } + + // Raw material availability options + public static function availabilityOptions() + { + return ['AVAILABLE' => 'Available', 'NOT_AVAILABLE' => 'Not Available', 'CONDITIONALLY_AVAILABLE' => 'Conditionally Available']; + } + + //get location + public function getLocation(){ + if ($this == null || $this->location == null) { + return ['No Infomation']; + } + $locationID = ItemLocations::where('item_id',$this->inventoryCode())->get()->first()->location_id; + if ($locationID == null){ + return null; + } else { + $count = $this->getNumberOfLocationsForItem($this); + $locationStrings = array(); + for ($i=0; $i < $count; $i++) { + $locationStrings[] = $this->getFullLocationPathAsString($this, $i); + } + return $locationStrings; + } + } + + public function getSearchResult(): SearchResult + { + $url = route('admin.raw_materials.show', $this); + return new SearchResult( + $this, + $this->title, + $url + ); + } + + public function getFullLocationPathByLocationID(int $id){ + $locationID = $id; + $locations_array = array(); + while (true) { + $thisLocation = Locations::where('id', $locationID)->get()[0]; + $locations_array[] = $thisLocation->location; + $locationID = $thisLocation->parent_location; + + if ($locationID == null) break; + } + + return $locations_array; + } + + public function getFullLocationPathAsString(Model $item, int $index){ + $location_array = $this->getFullLocationPathAsArray($item,$index); + return implode(' > ', array_reverse($location_array)); + } + + public function getFullLocationPathAsArray(Model $item, int $index) + { + $locations_array = array(); +// find the item location id from the item_locations table + $locationID = ItemLocations::where('item_id', $item->inventoryCode())->get(); + if ($locationID->count() > 0) { + $locationID = $locationID[$index]->location_id; + } else { + return $locations_array; + } + return $this->getFullLocationPathByLocationID($locationID); + } + + public function getNumberOfLocationsForItem(Model $item){ + $locationID = ItemLocations::where('item_id', $item->inventoryCode())->get(); + return $locationID->count(); + } + +} diff --git a/app/Models/Reservation.php b/app/Models/Reservation.php new file mode 100755 index 00000000..5efdf68c --- /dev/null +++ b/app/Models/Reservation.php @@ -0,0 +1,44 @@ +user_id != null) return $this->belongsTo(User::class, 'user_id', 'id'); + return null; + } + + public function st_info() + { + if ($this->station_id != null) return $this->belongsTo(Stations::class, 'station_id', 'id'); + return null; + } + + // Return the relative URL of the thumbnail + public function thumbURL() + { + if ($this->thumb != null) return '/img/reservations/' . $this->thumb; + return null; + } + + // Return the relative URL of the thumbnail after + public function thumbURL_after() + { + if ($this->thumb_after != null) return '/img/reservations_after/' . $this->thumb_after; + return null; + } +} + + \ No newline at end of file diff --git a/app/Models/Stations.php b/app/Models/Stations.php new file mode 100755 index 00000000..f323c2ed --- /dev/null +++ b/app/Models/Stations.php @@ -0,0 +1,25 @@ +id); + } + + // Return the relative URL of the thumbnail + public function thumbURL() + { + if ($this->thumb != null) return '/img/stations/' . $this->thumb; + return null; + } +} \ No newline at end of file diff --git a/app/Models/Traits/Uuid.php b/app/Models/Traits/Uuid.php old mode 100644 new mode 100755 diff --git a/app/Policies/OrderPolicy.php b/app/Policies/OrderPolicy.php new file mode 100755 index 00000000..8bb741d5 --- /dev/null +++ b/app/Policies/OrderPolicy.php @@ -0,0 +1,94 @@ +registerPolicies(); + $this->registerPolicies(); + + $frontEndUrl = env('FRONTEND_URL'); + $this->setFrontEndUrlInResetPasswordEmail($frontEndUrl); + // Implicitly grant "Admin" role all permissions // This works in the app by using gate-related functions like auth()->user->can() and @can() Gate::before(function ($user) { return $user->hasAllAccess() ? true : null; }); + + // Learn when to use this instead: https://docs.spatie.be/laravel-permission/v3/basic-usage/super-admin/#gate-after // Gate::after(function ($user) { // return $user->hasAllAccess(); // }); } + + protected function setFrontEndUrlInResetPasswordEmail($frontEndUrl = '') + { + // update url in ResetPassword Email to frontend url + ResetPassword::createUrlUsing(function ($user, string $token) use ($frontEndUrl) { + return $frontEndUrl . '/auth/password/email/reset?token=' . $token; + }); + } } diff --git a/app/Providers/BladeServiceProvider.php b/app/Providers/BladeServiceProvider.php old mode 100644 new mode 100755 diff --git a/app/Providers/BroadcastServiceProvider.php b/app/Providers/BroadcastServiceProvider.php old mode 100644 new mode 100755 diff --git a/app/Providers/ComposerServiceProvider.php b/app/Providers/ComposerServiceProvider.php old mode 100644 new mode 100755 diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php old mode 100644 new mode 100755 diff --git a/app/Providers/HelperServiceProvider.php b/app/Providers/HelperServiceProvider.php old mode 100644 new mode 100755 diff --git a/app/Providers/LocaleServiceProvider.php b/app/Providers/LocaleServiceProvider.php old mode 100644 new mode 100755 diff --git a/app/Providers/ObserverServiceProvider.php b/app/Providers/ObserverServiceProvider.php old mode 100644 new mode 100755 diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php old mode 100644 new mode 100755 index 5aa67dc3..1f0c7b55 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -29,7 +29,7 @@ class RouteServiceProvider extends ServiceProvider * * @var string|null */ - // protected $namespace = 'App\\Http\\Controllers'; + protected $namespace = 'App\\Http\\Controllers'; /** * Define your route model bindings, pattern filters, etc. @@ -50,11 +50,14 @@ public function boot() ->namespace($this->namespace) ->group(base_path('routes/web.php')); + // For the 'Login As' functionality from the 404labfr/laravel-impersonate package Route::middleware('web') ->group(function (Router $router) { $router->impersonate(); }); + + }); // To be able to restore a user, since the default binding is a find and would result in a 404 diff --git a/app/Rules/Captcha.php b/app/Rules/Captcha.php old mode 100644 new mode 100755 diff --git a/app/Rules/ValidateAsInternalEmail.php b/app/Rules/ValidateAsInternalEmail.php new file mode 100755 index 00000000..fc50baca --- /dev/null +++ b/app/Rules/ValidateAsInternalEmail.php @@ -0,0 +1,44 @@ +environment() == 'testing') return true; + $api = new DepartmentDataService(); + return $api->isInternalEmail($value); + } + + /** + * Get the validation error message. + * + * @return string + */ + public function message() + { + return "Only Department of Computer Engineering students/staff are allowed to register by themself."; + } +} diff --git a/app/Services/BaseService.php b/app/Services/BaseService.php old mode 100644 new mode 100755 diff --git a/app/Services/DepartmentDataService.php b/app/Services/DepartmentDataService.php new file mode 100755 index 00000000..e6f9f7d4 --- /dev/null +++ b/app/Services/DepartmentDataService.php @@ -0,0 +1,63 @@ +getData('/people/v1/students/all/'); + $student_emails = collect($students)->map(function ($user) { + $faculty_name = $user['emails']['faculty']['name']; + $faculty_domain = $user['emails']['faculty']['domain']; + + $personal_name = $user['emails']['faculty']['name']; + $personal_domain = $user['emails']['faculty']['domain']; + + if ($faculty_domain == 'eng.pdn.ac.lk' && $faculty_name != '' && $faculty_domain != '') { + // Faculty Email + return "$faculty_name@$faculty_domain"; + } else if ($personal_domain == 'eng.pdn.ac.lk') { + // Personal Email + return "$personal_name@$personal_domain"; + } + return null; + }); + + // Staff + $staff = $this->getData('/people/v1/staff/all/'); + $staff_emails = collect($staff)->map(function ($user) { + return $user['email']; + }); + + return $student_emails->union($staff_emails)->filter()->values()->toArray(); + } + ); + return in_array($userEmail, $emails); + } + + private function getData($endpoint) + { + $url = config('constants.department_data.base_url') . $endpoint; + $response = Http::get($url); + + if ($response->successful()) { + return $response->json(); + } else { + $statusCode = $response->status(); + $errorMessage = $response->body(); + + // TODO: Handle error + return []; + } + } +} diff --git a/artisan b/artisan old mode 100644 new mode 100755 diff --git a/bootstrap/app.php b/bootstrap/app.php old mode 100644 new mode 100755 diff --git a/composer.json b/composer.json old mode 100644 new mode 100755 index d5d2bbc1..d210d294 --- a/composer.json +++ b/composer.json @@ -20,24 +20,28 @@ "lab404/laravel-impersonate": "^1.6", "langleyfoxall/laravel-nist-password-rules": "^4.1", "laravel/framework": "^8.40", + "laravel/passport": "^10.1", + "laravel/sanctum": "^2.12", "laravel/socialite": "^5.0", "laravel/tinker": "^2.5", - "laravel/ui": "^3.0", + "laravel/ui": "^3.4", "laravelcollective/html": "^6.2", - "livewire/livewire": "^2.0", + "livewire/livewire": "^2.10", + "marvinlabs/laravel-discord-logger": "^1.3", "rappasoft/laravel-livewire-tables": "^1.0", "rappasoft/lockout": "^3.0", "spatie/laravel-activitylog": "^3.14", "spatie/laravel-permission": "^3.11", + "spatie/laravel-searchable": "^1.11", "tabuna/breadcrumbs": "^2.2" }, "require-dev": { - "barryvdh/laravel-debugbar": "^3.2", + "barryvdh/laravel-debugbar": "^3.6", "barryvdh/laravel-ide-helper": "^2.6", "brianium/paratest": "^6.2", "facade/ignition": "^2.5", "fakerphp/faker": "^1.9.1", - "friendsofphp/php-cs-fixer": "^2.16", + "friendsofphp/php-cs-fixer": "^2.18", "laravel/sail": "^1.0.1", "mockery/mockery": "^1.4.2", "nunomaduro/collision": "^5.0", @@ -99,7 +103,11 @@ "config": { "optimize-autoloader": true, "preferred-install": "dist", - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "treeware/plant": true, + "php-http/discovery": true + } }, "minimum-stability": "dev", "prefer-stable": true diff --git a/config/activitylog.php b/config/activitylog.php old mode 100644 new mode 100755 diff --git a/config/app.php b/config/app.php old mode 100644 new mode 100755 index a5587716..13bad904 --- a/config/app.php +++ b/config/app.php @@ -181,6 +181,7 @@ App\Providers\ObserverServiceProvider::class, App\Providers\RouteServiceProvider::class, + MarvinLabs\DiscordLogger\ServiceProvider::class ], /* @@ -237,4 +238,4 @@ 'Html' => Collective\Html\HtmlFacde::class, ], -]; +]; \ No newline at end of file diff --git a/config/auth.php b/config/auth.php old mode 100644 new mode 100755 index 16c949db..b588c809 --- a/config/auth.php +++ b/config/auth.php @@ -42,7 +42,7 @@ ], 'api' => [ - 'driver' => 'token', + 'driver' => 'sanctum', 'provider' => 'users', 'hash' => false, ], diff --git a/config/boilerplate.php b/config/boilerplate.php old mode 100644 new mode 100755 diff --git a/config/broadcasting.php b/config/broadcasting.php old mode 100644 new mode 100755 diff --git a/config/cache.php b/config/cache.php old mode 100644 new mode 100755 diff --git a/config/constants.php b/config/constants.php new file mode 100755 index 00000000..fc1f9fb2 --- /dev/null +++ b/config/constants.php @@ -0,0 +1,11 @@ + [ + 'dummy_thumb' => '/dummy/item_thumbnail.jpg', + ], + 'department_data' => [ + 'base_url' => 'https://api.ce.pdn.ac.lk', + 'cache_duration' => 43200 // 6 hours + ] +]; diff --git a/config/cors.php b/config/cors.php old mode 100644 new mode 100755 diff --git a/config/database.php b/config/database.php old mode 100644 new mode 100755 diff --git a/config/discord-logger.php b/config/discord-logger.php new file mode 100755 index 00000000..a7a00d82 --- /dev/null +++ b/config/discord-logger.php @@ -0,0 +1,61 @@ + [ + 'name' => env('APP_NAME', 'Discord Logger'), + 'avatar_url' => null, + ], + + /** + * The converter to use to turn a log record into a discord message + * + * Bundled converters: + * - \MarvinLabs\DiscordLogger\Converters\SimpleRecordConverter::class + * - \MarvinLabs\DiscordLogger\Converters\RichRecordConverter::class + */ + 'converter' => \MarvinLabs\DiscordLogger\Converters\RichRecordConverter::class, + + /** + * If enabled, stacktraces will be attached as files. If not, stacktraces will be directly printed out in the + * message. + * + * Valid values are: + * + * - 'smart': when stacktrace is less than 2000 characters, it is inlined with the message, else attached as file + * - 'file': stacktrace is always attached as file + * - 'inline': stacktrace is always inlined with the message, truncated if necessary + */ + 'stacktrace' => 'smart', + + /* + * A set of colors to associate to the different log levels when using the `RichRecordConverter` + */ + 'colors' => [ + 'DEBUG' => 0x607d8b, + 'INFO' => 0x4caf50, + 'NOTICE' => 0x2196f3, + 'WARNING' => 0xff9800, + 'ERROR' => 0xf44336, + 'CRITICAL' => 0xe91e63, + 'ALERT' => 0x673ab7, + 'EMERGENCY' => 0x9c27b0, + ], + + /* + * A set of emojis to associate to the different log levels. Set to null to disable an emoji for a given level + */ + 'emojis' => [ + 'DEBUG' => ':beetle:', + 'INFO' => ':bulb:', + 'NOTICE' => ':wink:', + 'WARNING' => ':flushed:', + 'ERROR' => ':poop:', + 'CRITICAL' => ':imp:', + 'ALERT' => ':japanese_ogre:', + 'EMERGENCY' => ':skull:', + ], +]; diff --git a/config/filesystems.php b/config/filesystems.php old mode 100644 new mode 100755 diff --git a/config/geoip.php b/config/geoip.php old mode 100644 new mode 100755 diff --git a/config/hashing.php b/config/hashing.php old mode 100644 new mode 100755 diff --git a/config/livewire-tables.php b/config/livewire-tables.php old mode 100644 new mode 100755 index 3cb57754..eb949f70 --- a/config/livewire-tables.php +++ b/config/livewire-tables.php @@ -4,5 +4,5 @@ /** * Options: tailwind | bootstrap-4 | bootstrap-5. */ - 'theme' => 'bootstrap-4', + 'theme' => 'bootstrap-5', ]; diff --git a/config/livewire.php b/config/livewire.php old mode 100644 new mode 100755 diff --git a/config/lockout.php b/config/lockout.php old mode 100644 new mode 100755 diff --git a/config/log-viewer.php b/config/log-viewer.php old mode 100644 new mode 100755 diff --git a/config/logging.php b/config/logging.php old mode 100644 new mode 100755 index 1aa06aa3..4cc8cb44 --- a/config/logging.php +++ b/config/logging.php @@ -62,6 +62,13 @@ 'level' => env('LOG_LEVEL', 'critical'), ], + 'discord' => [ + 'driver' => 'custom', + 'via' => MarvinLabs\DiscordLogger\Logger::class, + 'level' => 'debug', + 'url' => env('LOG_DISCORD_WEBHOOK_URL'), + ], + 'papertrail' => [ 'driver' => 'monolog', 'level' => env('LOG_LEVEL', 'debug'), @@ -102,4 +109,4 @@ ], ], -]; +]; \ No newline at end of file diff --git a/config/mail.php b/config/mail.php old mode 100644 new mode 100755 diff --git a/config/permission.php b/config/permission.php old mode 100644 new mode 100755 diff --git a/config/queue.php b/config/queue.php old mode 100644 new mode 100755 diff --git a/config/sanctum.php b/config/sanctum.php new file mode 100755 index 00000000..442726a7 --- /dev/null +++ b/config/sanctum.php @@ -0,0 +1,51 @@ + explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( + '%s%s', + 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', + env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : '' + ))), + + /* + |-------------------------------------------------------------------------- + | Expiration Minutes + |-------------------------------------------------------------------------- + | + | This value controls the number of minutes until an issued token will be + | considered expired. If this value is null, personal access tokens do + | not expire. This won't tweak the lifetime of first-party sessions. + | + */ + + 'expiration' => null, + + /* + |-------------------------------------------------------------------------- + | Sanctum Middleware + |-------------------------------------------------------------------------- + | + | When authenticating your first-party SPA with Sanctum you may need to + | customize some of the middleware Sanctum uses while processing the + | request. You may change the middleware listed below as required. + | + */ + + 'middleware' => [ + 'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class, + 'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class, + ], + +]; diff --git a/config/services.php b/config/services.php old mode 100644 new mode 100755 diff --git a/config/session.php b/config/session.php old mode 100644 new mode 100755 diff --git a/config/timezone.php b/config/timezone.php old mode 100644 new mode 100755 diff --git a/config/view.php b/config/view.php old mode 100644 new mode 100755 diff --git a/database/.gitignore b/database/.gitignore old mode 100644 new mode 100755 diff --git a/database/factories/AnnouncementFactory.php b/database/factories/AnnouncementFactory.php old mode 100644 new mode 100755 diff --git a/database/factories/ComponentItemFactory.php b/database/factories/ComponentItemFactory.php old mode 100644 new mode 100755 index e96dc519..f2c29209 --- a/database/factories/ComponentItemFactory.php +++ b/database/factories/ComponentItemFactory.php @@ -29,15 +29,11 @@ public function definition() 'quantity' => rand(100, 1000), 'specifications' => $this->faker->text(), 'description' => $this->faker->text(), - 'instructions' => $this->faker->text(), - 'isAvailable' => '1', - 'isElectrical' => '1', - 'powerRating' => rand(100, 1000), + 'datasheet' => $this->faker->url(), 'price' => rand(100, 1000), - 'size' => $this->faker->randomElement(['very small', 'small', 'medium','regular', 'large', 'very large']), 'thumb' => NULL, - 'component_type_id' => $this->faker->randomElement(['11','12']) + 'component_type_id' => $this->faker->randomElement(['10', '11', '12', '13', '14', '15']) ]; } -} +} \ No newline at end of file diff --git a/database/factories/ComponentTypeFactory.php b/database/factories/ComponentTypeFactory.php old mode 100644 new mode 100755 diff --git a/database/factories/ConsumableItemFactory.php b/database/factories/ConsumableItemFactory.php new file mode 100755 index 00000000..5df2cd00 --- /dev/null +++ b/database/factories/ConsumableItemFactory.php @@ -0,0 +1,32 @@ + '', + 'title' => $this->faker->name(), + 'quantity' => rand(100, 1000), + 'specifications' => $this->faker->text(), +// 'description' => $this->faker->text(), +// 'instructions' => $this->faker->text(), +// 'powerRating' => rand(100, 1000), + 'formFactor' => $this->faker->title(), +// 'voltageRating' => $this->faker->title(), + 'datasheetURL' => $this->faker->title(), + 'price' => rand(100, 1000), + 'thumb' => NULL, + 'consumable_type_id' => $this->faker->randomElement(['11', '30']) + ]; + } +} diff --git a/database/factories/ConsumableTypeFactory.php b/database/factories/ConsumableTypeFactory.php new file mode 100755 index 00000000..2f53aced --- /dev/null +++ b/database/factories/ConsumableTypeFactory.php @@ -0,0 +1,25 @@ + '', + 'parent_id' => NULL, + 'title' => $this->faker->title(), + 'subtitle' => $this->faker->title(), + 'description' => $this->faker->paragraph(), + 'thumb' => NULL + ]; + } +} diff --git a/database/factories/EquipmentItemFactory.php b/database/factories/EquipmentItemFactory.php old mode 100644 new mode 100755 diff --git a/database/factories/EquipmentTypeFactory.php b/database/factories/EquipmentTypeFactory.php old mode 100644 new mode 100755 diff --git a/database/factories/ItemLocationsFactory.php b/database/factories/ItemLocationsFactory.php new file mode 100755 index 00000000..5eaf5450 --- /dev/null +++ b/database/factories/ItemLocationsFactory.php @@ -0,0 +1,26 @@ +random(1)->first(); + $inventory_code = $item->inventoryCode(); + return [ + 'location_id' => '1', + 'item_id' => $inventory_code + ]; + } +} diff --git a/database/factories/JobRequestsFactory.php b/database/factories/JobRequestsFactory.php new file mode 100755 index 00000000..1475212a --- /dev/null +++ b/database/factories/JobRequestsFactory.php @@ -0,0 +1,47 @@ + 2, + 'supervisor' => 3, + 'student_notes' => $this->faker->text(), + 'supervisor_notes' => $this->faker->text(), + 'other_notes' => $this->faker->text(), + 'machine' => 1, + 'material' => 1, + 'status' => array_rand($status), + 'file' => $this->faker->file(), + 'thumb' => $this->faker->file(), + 'requested_time' => $this->faker->time(), + 'approved_time' => $this->faker->time(), + 'scheduled_time' => $this->faker->time(), + 'started_time' => $this->faker->time(), + 'completed_time' => $this->faker->time(), + 'finished_time' => $this->faker->time(), + 'material_usage' => rand(10, 100), + 'machine_time' => rand(10, 100) + ]; + } +} diff --git a/database/factories/LocationsFactory.php b/database/factories/LocationsFactory.php new file mode 100755 index 00000000..8d0e05f3 --- /dev/null +++ b/database/factories/LocationsFactory.php @@ -0,0 +1,24 @@ + $this->faker->name(), + 'parent_location' => '1', + 'x' => $this->faker->numberBetween(0, 100), + 'y' => $this->faker->numberBetween(0, 100), + 'z' => $this->faker->numberBetween(0, 100) + ]; + } +} diff --git a/database/factories/MachinesFactory.php b/database/factories/MachinesFactory.php new file mode 100755 index 00000000..8405cd6a --- /dev/null +++ b/database/factories/MachinesFactory.php @@ -0,0 +1,41 @@ + $this->faker->name, + 'type' => array_rand($types), + 'build_width' => rand(10, 100), + 'build_length' => rand(10, 100), + 'build_height' => rand(10, 100), + 'power' => rand(30, 100), + 'thumb' => NULL, + 'specifications' => $this->faker->text(), + 'status' => array_rand($availabilityOptions), + 'notes' => $this->faker->text(), + 'lifespan' => rand(10, 3000) + ]; + } +} diff --git a/database/factories/OrderFactory.php b/database/factories/OrderFactory.php new file mode 100755 index 00000000..fa179388 --- /dev/null +++ b/database/factories/OrderFactory.php @@ -0,0 +1,36 @@ + $this->faker->date(), + 'picked_date'=>NULL, + 'due_date_to_return' => $this->faker->date(), + 'returned_date'=>NULL, + 'user_id' => User::all()->random()->id , + 'status' => $this->faker->randomElement(['pending','progress', 'ready', 'pickedup']) + ]; + } +} diff --git a/database/factories/RawMaterialsFactory.php b/database/factories/RawMaterialsFactory.php new file mode 100755 index 00000000..8054ee9d --- /dev/null +++ b/database/factories/RawMaterialsFactory.php @@ -0,0 +1,35 @@ + $this->faker->name, + 'color' => "red", + 'specifications' => $this->faker->text(), + 'description' => $this->faker->text(), + 'quantity' => rand(1, 10), + 'unit' => 'pcs', + 'availability' => array_rand($availabilityOptions), + ]; + } +} diff --git a/database/factories/ReservationFactory.php b/database/factories/ReservationFactory.php new file mode 100755 index 00000000..da37966d --- /dev/null +++ b/database/factories/ReservationFactory.php @@ -0,0 +1,34 @@ + $this->faker->randomElement(['1','5']), + 'start_date' => $this->faker->dateTimeBetween($startDate = '-1 years', $endDate = 'now'), + 'end_date' => $this->faker->dateTimeBetween($startDate = '-1 years', $endDate = 'now'), + 'station_id' => $this->faker->randomElement(['1','5']), + 'E_numbers' => 'E/18/147, E/18/242, E/18/379', + 'duration' => $this->faker->randomElement(['30','240']), + + ]; + } +} diff --git a/database/factories/RoleFactory.php b/database/factories/RoleFactory.php old mode 100644 new mode 100755 index 8c0568e1..82d03999 --- a/database/factories/RoleFactory.php +++ b/database/factories/RoleFactory.php @@ -26,7 +26,7 @@ class RoleFactory extends Factory public function definition() { return [ - 'type' => $this->faker->randomElement([User::TYPE_ADMIN, User::TYPE_USER]), + 'type' => $this->faker->randomElement([User::TYPE_ADMIN, User::TYPE_USER, User::TYPE_LECTURER, User::TYPE_TECH_OFFICER, User::TYPE_MAINTAINER]), 'name' => $this->faker->word, ]; } diff --git a/database/factories/StationsFactory.php b/database/factories/StationsFactory.php new file mode 100755 index 00000000..a0a0751a --- /dev/null +++ b/database/factories/StationsFactory.php @@ -0,0 +1,32 @@ + $this->faker->name(), + 'description' => $this->faker->text(), + 'thumb' => NULL, + 'capacity' => $this->faker->randomElement(['1','4']), + + ]; + } +} diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php old mode 100644 new mode 100755 index 589e89bf..3fc2ac03 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -26,7 +26,7 @@ class UserFactory extends Factory public function definition() { return [ - 'type' => $this->faker->randomElement([User::TYPE_ADMIN, User::TYPE_USER]), + 'type' => $this->faker->randomElement([User::TYPE_ADMIN, User::TYPE_USER, User::TYPE_LECTURER, User::TYPE_TECH_OFFICER, User::TYPE_MAINTAINER]), 'name' => $this->faker->name(), 'email' => $this->faker->unique()->safeEmail(), 'email_verified_at' => now(), @@ -61,6 +61,42 @@ public function user() }); } + /** + * @return UserFactory + */ + public function lecturer() + { + return $this->state(function (array $attributes) { + return [ + 'type' => User::TYPE_LECTURER, + ]; + }); + } + + /** + * @return UserFactory + */ + public function techOfficer() + { + return $this->state(function (array $attributes) { + return [ + 'type' => User::TYPE_TECH_OFFICER, + ]; + }); + } + + /** + * @return UserFactory + */ + public function maintainer() + { + return $this->state(function (array $attributes) { + return [ + 'type' => User::TYPE_MAINTAINER, + ]; + }); + } + /** * @return UserFactory */ diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php old mode 100644 new mode 100755 index 78be80c7..c0d782dd --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -13,11 +13,13 @@ class CreateUsersTable extends Migration * @return void */ public function up() - { + { Schema::create('users', function (Blueprint $table) { $table->bigIncrements('id'); - $table->enum('type', [User::TYPE_ADMIN, User::TYPE_USER])->default(User::TYPE_USER); + + $table->enum('type', [User::TYPE_ADMIN, User::TYPE_USER, User::TYPE_LECTURER, User::TYPE_TECH_OFFICER, User::TYPE_MAINTAINER])->default(User::TYPE_USER); $table->string('name'); + $table->string('email')->unique()->nullable(); $table->timestamp('email_verified_at')->nullable(); $table->string('password')->nullable(); diff --git a/database/migrations/2014_10_12_100000_create_password_resets_table.php b/database/migrations/2014_10_12_100000_create_password_resets_table.php old mode 100644 new mode 100755 diff --git a/database/migrations/2019_08_19_000000_create_failed_jobs_table.php b/database/migrations/2019_08_19_000000_create_failed_jobs_table.php old mode 100644 new mode 100755 diff --git a/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php new file mode 100755 index 00000000..3ce00023 --- /dev/null +++ b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php @@ -0,0 +1,36 @@ +bigIncrements('id'); + $table->morphs('tokenable'); + $table->string('name'); + $table->string('token', 64)->unique(); + $table->text('abilities')->nullable(); + $table->timestamp('last_used_at')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('personal_access_tokens'); + } +} diff --git a/database/migrations/2020_02_25_034148_create_permission_tables.php b/database/migrations/2020_02_25_034148_create_permission_tables.php old mode 100644 new mode 100755 index f4fcf646..e7ce590d --- a/database/migrations/2020_02_25_034148_create_permission_tables.php +++ b/database/migrations/2020_02_25_034148_create_permission_tables.php @@ -19,7 +19,7 @@ public function up() Schema::create($tableNames['permissions'], function (Blueprint $table) use ($tableNames) { $table->bigIncrements('id'); - $table->enum('type', [User::TYPE_ADMIN, User::TYPE_USER]); + $table->enum('type', [User::TYPE_ADMIN, User::TYPE_USER, User::TYPE_LECTURER, User::TYPE_TECH_OFFICER, User::TYPE_MAINTAINER]); $table->string('guard_name'); $table->string('name'); $table->string('description')->nullable(); @@ -35,7 +35,7 @@ public function up() Schema::create($tableNames['roles'], function (Blueprint $table) { $table->bigIncrements('id'); - $table->enum('type', [User::TYPE_ADMIN, User::TYPE_USER]); + $table->enum('type', [User::TYPE_ADMIN, User::TYPE_USER, User::TYPE_LECTURER, User::TYPE_TECH_OFFICER, User::TYPE_MAINTAINER]); $table->string('name'); $table->string('guard_name'); $table->timestamps(); @@ -54,7 +54,7 @@ public function up() ->onDelete('cascade'); $table->primary(['permission_id', $columnNames['model_morph_key'], 'model_type'], - 'model_has_permissions_permission_model_type_primary'); + 'model_has_permissions_permission_model_type_primary'); }); Schema::create($tableNames['model_has_roles'], function (Blueprint $table) use ($tableNames, $columnNames) { @@ -70,7 +70,7 @@ public function up() ->onDelete('cascade'); $table->primary(['role_id', $columnNames['model_morph_key'], 'model_type'], - 'model_has_roles_role_model_type_primary'); + 'model_has_roles_role_model_type_primary'); }); Schema::create($tableNames['role_has_permissions'], function (Blueprint $table) use ($tableNames) { diff --git a/database/migrations/2020_05_25_021239_create_announcements_table.php b/database/migrations/2020_05_25_021239_create_announcements_table.php old mode 100644 new mode 100755 diff --git a/database/migrations/2020_05_29_020244_create_password_histories_table.php b/database/migrations/2020_05_29_020244_create_password_histories_table.php old mode 100644 new mode 100755 diff --git a/database/migrations/2020_07_06_215139_create_activity_log_table.php b/database/migrations/2020_07_06_215139_create_activity_log_table.php old mode 100644 new mode 100755 diff --git a/database/migrations/2021_04_05_153840_create_two_factor_authentications_table.php b/database/migrations/2021_04_05_153840_create_two_factor_authentications_table.php old mode 100644 new mode 100755 diff --git a/database/migrations/2021_07_28_190229_create_equipment_types_table.php b/database/migrations/2021_07_28_190229_create_equipment_types_table.php old mode 100644 new mode 100755 diff --git a/database/migrations/2021_07_28_190230_create_equipment_items_table.php b/database/migrations/2021_07_28_190230_create_equipment_items_table.php old mode 100644 new mode 100755 diff --git a/database/migrations/2021_08_26_174701_create_component_types_table.php b/database/migrations/2021_08_26_174701_create_component_types_table.php old mode 100644 new mode 100755 diff --git a/database/migrations/2021_08_28_190230_create_component_items_table.php b/database/migrations/2021_08_28_190230_create_component_items_table.php old mode 100644 new mode 100755 index 1b857cfc..19f4bace --- a/database/migrations/2021_08_28_190230_create_component_items_table.php +++ b/database/migrations/2021_08_28_190230_create_component_items_table.php @@ -7,10 +7,10 @@ class CreateComponentItemsTable extends Migration { /** - * Run the migrations. - * - * @return void - */ + * Run the migrations. + * + * @return void + */ public function up() { Schema::create('component_items', function (Blueprint $table) { @@ -20,22 +20,15 @@ public function up() $table->string("title"); $table->string("brand")->nullable(); $table->string("productCode")->nullable(); - $table->integer("quantity")->nullable(); + $table->integer("quantity")->nullable()->default(0); $table->text("specifications")->nullable(); $table->text("description")->nullable(); - $table->text("instructions")->nullable(); - + $table->text("datasheet")->nullable(); - $table->boolean("isAvailable")->nullable();; - $table->boolean("isElectrical")->nullable();; - $table->float("powerRating")->nullable() ; $table->float("price")->nullable(); // in LKR $table->string('thumb')->nullable(); - // Physical size in terms of appearance [small, medium, large] kind of - //!tendable - $table->enum('size', ['very small', 'small', 'medium','regular', 'large', 'very large']); $table->timestamps(); $table->foreignId('component_type_id') @@ -43,18 +36,16 @@ public function up() ->references('id') ->onDelete('cascade') ->on('component_types'); - }); - } /** - * Reverse the migrations. - * - * @return void - */ + * Reverse the migrations. + * + * @return void + */ public function down() { Schema::dropIfExists('component_items'); } -} +} \ No newline at end of file diff --git a/database/migrations/2021_09_20_202557_create_orders_table.php b/database/migrations/2021_09_20_202557_create_orders_table.php new file mode 100755 index 00000000..a6a92f5d --- /dev/null +++ b/database/migrations/2021_09_20_202557_create_orders_table.php @@ -0,0 +1,43 @@ +id(); + $table->date("ordered_date"); + $table->date("picked_date")->nullable(); + $table->date("due_date_to_return")->nullable(); + $table->date("returned_date")->nullable(); + $table->integer("otp")->nullable(); + $table->enum('status', ['pending','progress', 'ready', 'pickedup'])->default('pending'); + $table->timestamps(); + + $table->foreignId('user_id') + ->constrained() + ->references('id') + ->onDelete('cascade') + ->on('users'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('orders'); + } +} diff --git a/database/migrations/2021_09_22_210808_create_component_item_order_table.php b/database/migrations/2021_09_22_210808_create_component_item_order_table.php new file mode 100755 index 00000000..e07c90e6 --- /dev/null +++ b/database/migrations/2021_09_22_210808_create_component_item_order_table.php @@ -0,0 +1,51 @@ +bigIncrements('id'); + + $table->timestamps(); + + $table->integer('quantity')->default(0); + + + $table->foreignId('component_item_id') + ->constrained() + ->references('id') + ->onDelete('cascade') + ->on('component_items'); + + $table->foreignId('order_id') + ->constrained() + ->references('id') + ->onDelete('cascade') + ->on('orders'); + + + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('component_item_order'); + } +} + diff --git a/database/migrations/2021_10_22_054544_create_machines_table.php b/database/migrations/2021_10_22_054544_create_machines_table.php new file mode 100755 index 00000000..f67e82ec --- /dev/null +++ b/database/migrations/2021_10_22_054544_create_machines_table.php @@ -0,0 +1,46 @@ +id(); + $table->char("code", 8)->default(''); + $table->string("title"); + $table->enum('type', array_keys(\App\Models\Machines::types())); + + $table->float("build_width")->nullable(); // in mm + $table->float("build_length")->nullable(); // in mm + $table->float("build_height")->nullable(); // in mm + + $table->float("power")->nullable(); // in Watts + $table->string('thumb')->nullable(); + + $table->text("specifications")->nullable(); + $table->enum('status', array_keys(\App\Models\Machines::availabilityOptions())); + $table->text("notes")->nullable(); + $table->float("lifespan")->default(0); // in minutes + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('machines'); + } +} diff --git a/database/migrations/2021_10_22_054722_create_raw_materials_table.php b/database/migrations/2021_10_22_054722_create_raw_materials_table.php new file mode 100755 index 00000000..45ea9c1c --- /dev/null +++ b/database/migrations/2021_10_22_054722_create_raw_materials_table.php @@ -0,0 +1,41 @@ +id(); + $table->char("code", 8)->default(''); + $table->string("title"); + $table->string("color")->nullable(); + $table->text("description")->nullable(); + $table->text("specifications")->nullable(); + $table->float("quantity")->nullable(); // in units + $table->string("unit")->nullable(); + $table->string('thumb')->nullable(); + $table->enum('availability', array_keys(\App\Models\RawMaterials::availabilityOptions())); + $table->text("notes")->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('raw_materials'); + } +} diff --git a/database/migrations/2021_10_22_054803_create_job_requests_table.php b/database/migrations/2021_10_22_054803_create_job_requests_table.php new file mode 100755 index 00000000..a524ae89 --- /dev/null +++ b/database/migrations/2021_10_22_054803_create_job_requests_table.php @@ -0,0 +1,71 @@ +id(); + + $table->foreignId('student') + ->constrained() + ->references('id') + ->on('users'); + $table->foreignId('supervisor') + ->constrained() + ->references('id') + ->on('users'); + + $table->text("student_notes")->nullable(); + $table->text("supervisor_notes")->nullable(); + $table->text("other_notes")->nullable(); + + $table->foreignId('machine') + ->constrained() + ->references('id') + ->on('machines'); + + $table->foreignId('material') + ->constrained() + ->references('id') + ->on('raw_materials'); + + $table->enum("status", array_keys(\App\Models\JobRequests::job_status())); + + $table->string('file'); // zip file + $table->string('thumb')->nullable(); // preview file + + $table->timestamp('requested_time')->nullable(); + $table->timestamp('approved_time')->nullable(); + $table->timestamp('scheduled_time')->nullable(); + $table->timestamp('started_time')->nullable(); + $table->timestamp('completed_time')->nullable(); + $table->timestamp('finished_time')->nullable(); + + $table->float("material_usage")->nullable()->default(0); // in unit defined in the material + $table->integer('machine_time')->default(0); + + $table->timestamps(); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('job_requests'); + } +} diff --git a/database/migrations/2022_06_06_060603_create_consumable_types_table.php b/database/migrations/2022_06_06_060603_create_consumable_types_table.php new file mode 100755 index 00000000..0cf24fa4 --- /dev/null +++ b/database/migrations/2022_06_06_060603_create_consumable_types_table.php @@ -0,0 +1,37 @@ +id()->startingValue(10); + $table->integer("parent_id")->nullable(); + $table->char("code",8)->default(''); + $table->string("title"); + $table->string("subtitle")->nullable(); + $table->text("description")->nullable(); + $table->string("thumb")->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('consumable_types'); + } +} diff --git a/database/migrations/2022_06_07_021752_create_consumable_items_table.php b/database/migrations/2022_06_07_021752_create_consumable_items_table.php new file mode 100755 index 00000000..242fd1e9 --- /dev/null +++ b/database/migrations/2022_06_07_021752_create_consumable_items_table.php @@ -0,0 +1,53 @@ +id()->startingValue(1000); + $table->char("code", 8)->nullable(); + $table->string("title"); + $table->integer("quantity")->nullable()->default(0); + + $table->text("specifications")->nullable(); +// $table->text("description")->nullable(); +// $table->text("instructions")->nullable(); + +// $table->float("powerRating")->nullable(); + $table->text("formFactor")->nullable(); +// $table->text("voltageRating")->nullable(); + $table->text("datasheetURL")->nullable(); + $table->float("price")->nullable(); // in LKR + $table->string('thumb')->nullable(); + + $table->timestamps(); + + $table->foreignId('consumable_type_id') + ->constrained() + ->references('id') + ->onDelete('cascade') + ->on('consumable_types'); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('consumable_items'); + } +} diff --git a/database/migrations/2022_06_19_093341_create_locations_table.php b/database/migrations/2022_06_19_093341_create_locations_table.php new file mode 100755 index 00000000..7e5fdd4c --- /dev/null +++ b/database/migrations/2022_06_19_093341_create_locations_table.php @@ -0,0 +1,36 @@ +id(); + $table->string("location"); + $table->foreignId("parent_location")->nullable()->references("id")->on("locations")->onDelete("cascade"); + $table->integer("x")->nullable(); + $table->integer("y")->nullable(); + $table->integer("z")->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('locations'); + } +} diff --git a/database/migrations/2022_06_19_104802_create_item_locations_table.php b/database/migrations/2022_06_19_104802_create_item_locations_table.php new file mode 100755 index 00000000..494a32f7 --- /dev/null +++ b/database/migrations/2022_06_19_104802_create_item_locations_table.php @@ -0,0 +1,37 @@ +id(); + $table->foreignId('location_id')->constrained()->onDelete('cascade'); + $table->string("item_id"); + $table->integer("x")->nullable(); + $table->integer("y")->nullable(); + $table->integer("z")->nullable(); +// TODO: add orientation if needed + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('item_locations'); + } +} diff --git a/database/migrations/2022_06_22_091455_create_stations_table.php b/database/migrations/2022_06_22_091455_create_stations_table.php new file mode 100755 index 00000000..493b4d51 --- /dev/null +++ b/database/migrations/2022_06_22_091455_create_stations_table.php @@ -0,0 +1,35 @@ +id(); + $table->string("stationName"); + $table->text("description")->nullable(); + $table->string('thumb')->nullable(); + $table->integer("capacity")->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('stations'); + } +} diff --git a/database/migrations/2022_06_22_123753_create_reservations_table.php b/database/migrations/2022_06_22_123753_create_reservations_table.php new file mode 100755 index 00000000..13e63687 --- /dev/null +++ b/database/migrations/2022_06_22_123753_create_reservations_table.php @@ -0,0 +1,56 @@ +id(); + // $table->string('email'); + $table->foreignId('user_id') + ->references('id') + ->on('users'); + $table->dateTime('start_date'); + $table->dateTime('end_date'); + $table->foreignId('station_id') + ->constrained() + ->references('id') + ->onDelete('cascade') + ->on('stations'); + $table->string('E_numbers'); + $table->string('duration'); + $table->string('thumb')->nullable(); + $table->string('thumb_after')->nullable(); + $table->string('status')->nullable(); + $table->text('comments')->nullable(); + $table->timestamps(); + + + }); + + // Schema::table('reservations', function($table) { + // $table->foreign('email')->references('email')->on('users'); + // }); + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('reservations'); + } +} diff --git a/database/seeders/AnnouncementSeeder.php b/database/seeders/AnnouncementSeeder.php old mode 100644 new mode 100755 diff --git a/database/seeders/Auth/PermissionRoleSeeder.php b/database/seeders/Auth/PermissionRoleSeeder.php old mode 100644 new mode 100755 index 68c61deb..369e79f8 --- a/database/seeders/Auth/PermissionRoleSeeder.php +++ b/database/seeders/Auth/PermissionRoleSeeder.php @@ -23,12 +23,30 @@ public function run() $this->disableForeignKeys(); // Create Roles - Role::create([ + $userRole = Role::create([ 'id' => 1, 'type' => User::TYPE_ADMIN, 'name' => 'Administrator', ]); + $lecturerRole = Role::create([ + 'id' => 2, + 'type' => User::TYPE_LECTURER, + 'name' => 'Lecturer', + ]); + + $techOfficer = Role::create([ + 'id' => 3, + 'type' => User::TYPE_TECH_OFFICER, + 'name' => 'Technical Officer', + ]); + + $maintainer = Role::create([ + 'id' => 4, + 'type' => User::TYPE_MAINTAINER, + 'name' => 'Maintainer', + ]); + // Non Grouped Permissions // @@ -39,7 +57,6 @@ public function run() 'name' => 'admin.access.user', 'description' => 'All User Permissions', ]); - $users->children()->saveMany([ new Permission([ 'type' => User::TYPE_ADMIN, @@ -78,6 +95,46 @@ public function run() ]), ]); + $lecturers = Permission::create([ + 'type' => User::TYPE_LECTURER, + 'name' => 'lecturer.access', + 'description' => 'All Lecturer Permissions', + ]); + $lecturers->children()->saveMany([ + new Permission([ + 'type' => User::TYPE_LECTURER, + 'name' => 'lecturer.access.all', + 'description' => 'Access All', + ]) + ]); + + $techOfficers = Permission::create([ + 'type' => User::TYPE_TECH_OFFICER, + 'name' => 'techOfficer.access', + 'description' => 'All Technical Officer Permissions', + ]); + // $techOfficers->children()->saveMany([ + // new Permission([ + // 'type' => User::TYPE_TECH_OFFICER, + // 'name' => 'techofficer.access.all', + // 'description' => 'Access All', + // ]) + // ]); + + $maintainers = Permission::create([ + 'type' => User::TYPE_MAINTAINER, + 'name' => 'maintainer.access', + 'description' => 'All Maintainer Permissions', + ]); + // $maintainer->children()->saveMany([ + // new Permission([ + // 'type' => User::TYPE_MAINTAINER, + // 'name' => 'maintainer.access.all', + // 'description' => 'Access All', + // ]) + // ]); + + // Assign Permissions to other Roles // diff --git a/database/seeders/Auth/UserRoleSeeder.php b/database/seeders/Auth/UserRoleSeeder.php old mode 100644 new mode 100755 index 22a3773e..48fead48 --- a/database/seeders/Auth/UserRoleSeeder.php +++ b/database/seeders/Auth/UserRoleSeeder.php @@ -22,6 +22,15 @@ public function run() User::find(1)->assignRole(config('boilerplate.access.role.admin')); + // Assign permissions for the lecturer users + User::where('type', User::TYPE_LECTURER)->first()->assignRole('Lecturer'); + + // Assign permissions for the technicalOfficer users + User::where('type', User::TYPE_TECH_OFFICER)->first()->assignRole('Technical Officer'); + + // Assign permissions for the maintainer users + User::where('type', User::TYPE_MAINTAINER)->first()->assignRole('Maintainer'); + $this->enableForeignKeys(); } } diff --git a/database/seeders/Auth/UserSeeder.php b/database/seeders/Auth/UserSeeder.php old mode 100644 new mode 100755 index 23ad03b4..e3f90f39 --- a/database/seeders/Auth/UserSeeder.php +++ b/database/seeders/Auth/UserSeeder.php @@ -24,7 +24,7 @@ public function run() User::create([ 'type' => User::TYPE_ADMIN, 'name' => 'Super Admin', - 'email' => env('SEED_ADMIN_EMAIL', 'admin@admin.com'), + 'email' => env('SEED_ADMIN_EMAIL', 'admin@example.com'), 'password' => env('SEED_ADMIN_PASSWORD', 'admin_user'), 'email_verified_at' => now(), 'active' => true, @@ -34,11 +34,38 @@ public function run() User::create([ 'type' => User::TYPE_USER, 'name' => 'Test User', - 'email' => env('SEED_USER_EMAIL', 'user@user.com'), + 'email' => env('SEED_USER_EMAIL', 'user@example.com'), 'password' => env('SEED_USER_PASSWORD', 'regular_user'), 'email_verified_at' => now(), 'active' => true, ]); + + $lecturer = User::create([ + 'type' => User::TYPE_LECTURER, + 'name' => 'Lecturer User', + 'email' => env('SEED_LECTURER_EMAIL', 'lecturer@example.com'), + 'password' => env('SEED_LECTURER_PASSWORD', 'lecturer_user'), + 'email_verified_at' => now(), + 'active' => true, + ]); + + $techOfficer = User::create([ + 'type' => User::TYPE_TECH_OFFICER, + 'name' => 'Technical Officer User', + 'email' => env('SEED_TECH_OFFICER_EMAIL', 'techofficer@example.com'), + 'password' => env('SEED_TECH_OFFICER_PASSWORD', 'tech_officer_user'), + 'email_verified_at' => now(), + 'active' => true, + ]); + + $maintainer = User::create([ + 'type' => User::TYPE_MAINTAINER, + 'name' => 'Maintainer User', + 'email' => env('SEED_MAINTAINER_EMAIL', 'maintainer@example.com'), + 'password' => env('SEED_MAINTAINER_PASSWORD', 'maintainer_user'), + 'email_verified_at' => now(), + 'active' => true, + ]); } $this->enableForeignKeys(); diff --git a/database/seeders/AuthSeeder.php b/database/seeders/AuthSeeder.php old mode 100644 new mode 100755 diff --git a/database/seeders/ComponentItemSeeder.php b/database/seeders/ComponentItemSeeder.php old mode 100644 new mode 100755 index 42ddd0e9..0c392f28 --- a/database/seeders/ComponentItemSeeder.php +++ b/database/seeders/ComponentItemSeeder.php @@ -7,11 +7,7 @@ class ComponentItemSeeder extends Seeder { - protected $data = [ - - array('id' => '1001', 'code' => '', 'title' => 'Arduino UNO REV3', 'brand' => 'Arduino', 'productCode' => 'Uno v3', 'quantity' => '10', 'specifications' => 'ATMega328p Microcontroller', 'description' => 'The Arduino Uno is an open-source microcontroller board based on the Microchip ATmega328P microcontroller and developed by Arduino.cc. The board is equipped with sets of digital and analog input/output (I/O) pins that may be interfaced to various expansion boards (shields) and other circuits.', 'instructions' => NULL, 'isAvailable' => '1', 'isElectrical' => '1', 'powerRating' => NULL, 'price' => '1200.00', 'thumb' => 'comit1002.jpg', 'size' => 'medium', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'component_type_id' => '16'), - array('id' => '1002', 'code' => '', 'title' => '741 Operational Amplifier', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '50', 'specifications' => 'UA741CP OpAmp 1MHz', 'description' => 'The 741 Op Amp IC is a monolithic integrated circuit, comprising of a general purpose Operational Amplifier.', 'instructions' => NULL, 'isAvailable' => '1', 'isElectrical' => '1', 'powerRating' => NULL, 'price' => '80.00', 'thumb' => 'comit1002.jpg', 'size' => 'small', 'created_at' => '2021-08-04 15:26:56', 'updated_at' => '2021-09-02 05:42:11', 'component_type_id' => '17') - ]; + protected $data = []; /** * Run the database seeds. @@ -31,4 +27,4 @@ public function run() $this->command->info('Inserted ' . count($this->data) . ' records to component_items table'); } -} +} \ No newline at end of file diff --git a/database/seeders/ComponentTypeSeeder.php b/database/seeders/ComponentTypeSeeder.php old mode 100644 new mode 100755 index c32967e6..a57f26fe --- a/database/seeders/ComponentTypeSeeder.php +++ b/database/seeders/ComponentTypeSeeder.php @@ -8,13 +8,67 @@ class ComponentTypeSeeder extends Seeder { protected $data = [ - array('id' => '11', 'parent_id' => NULL, 'code' => '', 'title' => 'Inteiligent Components', 'subtitle' => '', 'description' => ' ', 'thumb' => 'comit1002.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2021-07-04 15:21:03'), - array('id' => '12', 'parent_id' => NULL, 'code' => '', 'title' => 'Non-Inteiligent Components', 'subtitle' => '', 'description' => ' ', 'thumb' => 'comit1002.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2021-07-04 15:21:03'), - array('id' => '13', 'parent_id' => NULL, 'code' => '', 'title' => 'Simple Circuit Components', 'subtitle' => '', 'description' => ' ', 'thumb' => 'comit1002.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2021-07-04 15:21:03'), - array('id' => '14', 'parent_id' => NULL, 'code' => '', 'title' => 'Non-Electonic Components', 'subtitle' => '', 'description' => ' ', 'thumb' => 'comit1002.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2021-07-04 15:21:03'), - array('id' => '15', 'parent_id' => NULL, 'code' => '', 'title' => 'Other Components', 'subtitle' => '', 'description' => ' ', 'thumb' => 'comit1002.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2021-07-04 15:21:03'), - array('id' => '16', 'parent_id' => '11', 'code' => '', 'title' => 'Development Boards', 'subtitle' => '', 'description' => 'These boards incorporate the target microcontroller with additional memory, and some other peripheral interfaces.', 'thumb' => 'comit1002.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2021-07-04 15:21:03'), - array('id' => '17', 'parent_id' => '11', 'code' => '', 'title' => 'Integrated Circuits', 'subtitle' => 'ICs', 'description' => 'an assembly of electronic components with miniature devices built up on a semiconductor substrate', 'thumb' => 'comit1002.jpg', 'created_at' => '2021-07-04 15:22:56', 'updated_at' => '2021-09-02 05:19:38') + array('id' => '10', 'parent_id' => NULL, 'title' => 'Developemnt Boards', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '11', 'parent_id' => '10', 'title' => 'Arduino', 'subtitle' => NULL, 'description' => 'Arduino based development boards', 'thumb' => NULL), + array('id' => '12', 'parent_id' => '10', 'title' => 'Espressif', 'subtitle' => NULL, 'description' => 'ESP development boards', 'thumb' => NULL), + array('id' => '13', 'parent_id' => '10', 'title' => 'STM', 'subtitle' => NULL, 'description' => 'STM famility development boards', 'thumb' => NULL), + array('id' => '14', 'parent_id' => '10', 'title' => 'Raspberry Pi', 'subtitle' => NULL, 'description' => 'Raspberry Pi based development boards', 'thumb' => NULL), + array('id' => '15', 'parent_id' => '10', 'title' => 'PIC', 'subtitle' => NULL, 'description' => 'PIC family development boards', 'thumb' => NULL), + array('id' => '20', 'parent_id' => NULL, 'title' => 'Sensors', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '21', 'parent_id' => '20', 'title' => 'Voltage', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '22', 'parent_id' => '20', 'title' => 'Current', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '23', 'parent_id' => '20', 'title' => 'Light and Color', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '24', 'parent_id' => '20', 'title' => 'GPS', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '25', 'parent_id' => '20', 'title' => 'Pressure', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '26', 'parent_id' => '20', 'title' => 'Temperature and Humidity', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '27', 'parent_id' => '20', 'title' => 'Distance', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '28', 'parent_id' => '20', 'title' => 'Motion', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '29', 'parent_id' => '20', 'title' => 'RFID', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '30', 'parent_id' => '20', 'title' => 'Touch', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '31', 'parent_id' => '20', 'title' => 'Gas', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '32', 'parent_id' => '20', 'title' => 'Fingerprint', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '40', 'parent_id' => NULL, 'title' => 'Motor Drivers', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '41', 'parent_id' => '40', 'title' => 'DC Motor Drivers', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '42', 'parent_id' => '40', 'title' => 'Stepper Motor Drivers', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '43', 'parent_id' => '40', 'title' => 'Brushless Motor Drivers', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '50', 'parent_id' => NULL, 'title' => 'Transmiters and Receivers', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '51', 'parent_id' => '50', 'title' => 'RF', 'subtitle' => 'Radio Frequency', 'description' => NULL, 'thumb' => NULL), + array('id' => '52', 'parent_id' => '50', 'title' => 'Bluetooth', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '53', 'parent_id' => '50', 'title' => 'WiFi', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '54', 'parent_id' => '50', 'title' => 'GSM', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '60', 'parent_id' => NULL, 'title' => 'Readers and Converters', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '61', 'parent_id' => '60', 'title' => 'MicroSD', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '62', 'parent_id' => '60', 'title' => 'USB to TTL', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '63', 'parent_id' => '60', 'title' => 'RS232 to TTL', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '70', 'parent_id' => NULL, 'title' => 'Cameras', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '71', 'parent_id' => '70', 'title' => 'RPi Camera', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '80', 'parent_id' => NULL, 'title' => 'Arduino Shields', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '90', 'parent_id' => NULL, 'title' => 'Displays', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '91', 'parent_id' => '90', 'title' => 'LCD', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '92', 'parent_id' => '90', 'title' => 'OLED', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '93', 'parent_id' => '90', 'title' => 'LED', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '94', 'parent_id' => '90', 'title' => 'TFT', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '100', 'parent_id' => NULL, 'title' => 'Output Modules', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '101', 'parent_id' => '100', 'title' => 'Speakers', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '102', 'parent_id' => '100', 'title' => 'Relays', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '110', 'parent_id' => NULL, 'title' => 'Input Modules', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '111', 'parent_id' => '110', 'title' => 'Switches', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '112', 'parent_id' => '110', 'title' => 'Matrix Keypad', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '120', 'parent_id' => NULL, 'title' => 'Expansions and Cables', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '130', 'parent_id' => NULL, 'title' => 'Motors', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '131', 'parent_id' => '130', 'title' => 'DC Non-Geared', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '132', 'parent_id' => '130', 'title' => 'DC Geared', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '133', 'parent_id' => '130', 'title' => 'Stepper', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '134', 'parent_id' => '130', 'title' => 'Servo', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '135', 'parent_id' => '130', 'title' => 'Brushless', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '136', 'parent_id' => '130', 'title' => 'AC', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '140', 'parent_id' => NULL, 'title' => 'Measuring', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '141', 'parent_id' => '140', 'title' => 'Multimeters', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '142', 'parent_id' => '140', 'title' => 'Logic Probes', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '150', 'parent_id' => NULL, 'title' => 'ICs', 'subtitle' => 'Integrated Circuits', 'description' => NULL, 'thumb' => NULL), + array('id' => '151', 'parent_id' => '150', 'title' => 'Digital Logic', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '152', 'parent_id' => '150', 'title' => 'Amplifiers', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL), + array('id' => '153', 'parent_id' => '150', 'title' => 'Memory', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL) ]; /** @@ -31,7 +85,7 @@ public function run() $this->command->info("Insert failed at record $index."); return; } - $this->command->info('Inserted ' . count($this->data) . ' records to component_types table'); } + $this->command->info('Inserted ' . count($this->data) . ' records to component_types table'); } -} +} \ No newline at end of file diff --git a/database/seeders/ConsumableItemSeeder.php b/database/seeders/ConsumableItemSeeder.php new file mode 100755 index 00000000..c48f59c5 --- /dev/null +++ b/database/seeders/ConsumableItemSeeder.php @@ -0,0 +1,306 @@ + '1001', 'code' => '', 'title' => '10 Ω Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistor_10_ohm.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1002', 'code' => '', 'title' => '22 Ω Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistor_22_ohm.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1003', 'code' => '', 'title' => '47 Ω Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistor_47_ohm.png', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1004', 'code' => '', 'title' => '68 Ω Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistor_68_ohm.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1005', 'code' => '', 'title' => '100 Ω Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistor_100_ohm.jpeg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1006', 'code' => '', 'title' => '150 Ω Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistor_150_ohm.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1007', 'code' => '', 'title' => '220 Ω Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistor_220_ohm.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1008', 'code' => '', 'title' => '270 Ω Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistor_270_ohm.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1009', 'code' => '', 'title' => '330 Ω Resistor', 'quantity' => '0', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistor_330_ohm.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1010', 'code' => '', 'title' => '470 Ω Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1011', 'code' => '', 'title' => '510 Ω Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1012', 'code' => '', 'title' => '680 Ω Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1013', 'code' => '', 'title' => '1 kΩ Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1014', 'code' => '', 'title' => '2.2 kΩ Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1015', 'code' => '', 'title' => '3.3 kΩ Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1016', 'code' => '', 'title' => '4.7 kΩ Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1017', 'code' => '', 'title' => '5.1 kΩ Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1018', 'code' => '', 'title' => '6.8 kΩ Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1019', 'code' => '', 'title' => '10 kΩ Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1020', 'code' => '', 'title' => '22 kΩ Resistor', 'quantity' => '0', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1021', 'code' => '', 'title' => '33 kΩ Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1022', 'code' => '', 'title' => '47 kΩ Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1023', 'code' => '', 'title' => '51 kΩ Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1024', 'code' => '', 'title' => '68 kΩ Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1025', 'code' => '', 'title' => '100 kΩ Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1026', 'code' => '', 'title' => '220 kΩ Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1027', 'code' => '', 'title' => '330 kΩ Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1028', 'code' => '', 'title' => '470 kΩ Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1029', 'code' => '', 'title' => '510 kΩ Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1030', 'code' => '', 'title' => '680 kΩ Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1031', 'code' => '', 'title' => '1 MΩ Resistor', 'quantity' => '100', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'), + array('id' => '1032', 'code' => '', 'title' => '10 Ω Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1033', 'code' => '', 'title' => '22 Ω Resistor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1034', 'code' => '', 'title' => '47 Ω Resistor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1035', 'code' => '', 'title' => '68 Ω Resistor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1036', 'code' => '', 'title' => '100 Ω Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1037', 'code' => '', 'title' => '150 Ω Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1038', 'code' => '', 'title' => '220 Ω Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1039', 'code' => '', 'title' => '270 Ω Resistor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1040', 'code' => '', 'title' => '330 Ω Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1041', 'code' => '', 'title' => '470 Ω Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1042', 'code' => '', 'title' => '510 Ω Resistor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1043', 'code' => '', 'title' => '680 Ω Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1044', 'code' => '', 'title' => '1KΩ Resistor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1045', 'code' => '', 'title' => '2.2 kΩ Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1046', 'code' => '', 'title' => '3.3 kΩ Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1047', 'code' => '', 'title' => '4.7 kΩ Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1048', 'code' => '', 'title' => '5.1 kΩ Resistor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1049', 'code' => '', 'title' => '6.8 kΩ Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1050', 'code' => '', 'title' => '10 kΩ Resistor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1051', 'code' => '', 'title' => '22 kΩ Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1052', 'code' => '', 'title' => '33 kΩ Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1053', 'code' => '', 'title' => '47 kΩ Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1054', 'code' => '', 'title' => '51 kΩ Resistor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1055', 'code' => '', 'title' => '68 kΩ Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1056', 'code' => '', 'title' => '100 kΩ Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1057', 'code' => '', 'title' => '220 kΩ Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1058', 'code' => '', 'title' => '330 kΩ Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1059', 'code' => '', 'title' => '470 kΩ Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1060', 'code' => '', 'title' => '510 kΩ Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1061', 'code' => '', 'title' => '680 kΩ Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1062', 'code' => '', 'title' => '1 MΩ Resistor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '0.50', 'thumb' => 'resistors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'), + array('id' => '1063', 'code' => '', 'title' => '0.1 uF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '1.50', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '15'), + array('id' => '1064', 'code' => '', 'title' => '0.22 uF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '1.50', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '15'), + array('id' => '1065', 'code' => '', 'title' => '0.33 uF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '1.50', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '15'), + array('id' => '1066', 'code' => '', 'title' => '0.47 uF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '1.50', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '15'), + array('id' => '1067', 'code' => '', 'title' => '2.2 uF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '1.50', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '15'), + array('id' => '1068', 'code' => '', 'title' => '3.3 uF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '15'), + array('id' => '1069', 'code' => '', 'title' => '4.7 uF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '15'), + array('id' => '1070', 'code' => '', 'title' => '10 uF Capacitor', 'quantity' => '50', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '1.50', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '15'), + array('id' => '1071', 'code' => '', 'title' => '22 uF Capacitor', 'quantity' => '50', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '1.50', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '15'), + array('id' => '1072', 'code' => '', 'title' => '47 uF Capacitor', 'quantity' => '50', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '1.50', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '15'), + array('id' => '1073', 'code' => '', 'title' => '100 uF Capacitor', 'quantity' => '50', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '15'), + array('id' => '1074', 'code' => '', 'title' => '220 uF Capacitor', 'quantity' => '50', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '3.50', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '15'), + array('id' => '1075', 'code' => '', 'title' => '330 uF Capacitor', 'quantity' => '50', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '15'), + array('id' => '1076', 'code' => '', 'title' => '470 uF Capacitor', 'quantity' => '50', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '3.50', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '15'), + array('id' => '1077', 'code' => '', 'title' => '1000 uF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '10.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '15'), + array('id' => '1078', 'code' => '', 'title' => '10 pF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1079', 'code' => '', 'title' => '20 pF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1080', 'code' => '', 'title' => '30 pF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1081', 'code' => '', 'title' => '47 pF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1082', 'code' => '', 'title' => '68 pF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1083', 'code' => '', 'title' => '100 pF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1084', 'code' => '', 'title' => '220 pF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1085', 'code' => '', 'title' => '330 pF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1086', 'code' => '', 'title' => '470 pF Capacitor', 'quantity' => '50', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1087', 'code' => '', 'title' => '680 pF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1088', 'code' => '', 'title' => '1 nF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1089', 'code' => '', 'title' => '2.2 nF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1090', 'code' => '', 'title' => '3.3 nF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1091', 'code' => '', 'title' => '4.7 nF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1092', 'code' => '', 'title' => '6.8 nF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1093', 'code' => '', 'title' => '10 nF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1094', 'code' => '', 'title' => '22 nF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1095', 'code' => '', 'title' => '33 nF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1096', 'code' => '', 'title' => '47 nF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1097', 'code' => '', 'title' => '68 nF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1098', 'code' => '', 'title' => '100 nF Capacitor', 'quantity' => '50', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1099', 'code' => '', 'title' => '220 nF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1100', 'code' => '', 'title' => '330 nF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1101', 'code' => '', 'title' => '470 nF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1102', 'code' => '', 'title' => '680 nF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1103', 'code' => '', 'title' => '1 uF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1104', 'code' => '', 'title' => '2.2 uF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1105', 'code' => '', 'title' => '3.3 uF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1106', 'code' => '', 'title' => '4.7 uF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1107', 'code' => '', 'title' => '6.8 uF Capacitor', 'quantity' => '0', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '0.75', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'), + array('id' => '1108', 'code' => '', 'title' => '1 pF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1109', 'code' => '', 'title' => '2.2 pF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1110', 'code' => '', 'title' => '3.3 pF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1111', 'code' => '', 'title' => '4.7 pF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1112', 'code' => '', 'title' => '6.8 pF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1113', 'code' => '', 'title' => '10 pF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1114', 'code' => '', 'title' => '22 pF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1115', 'code' => '', 'title' => '33 pF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1116', 'code' => '', 'title' => '47 pF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1117', 'code' => '', 'title' => '68 pF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1118', 'code' => '', 'title' => '100 pF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1119', 'code' => '', 'title' => '220 pF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1120', 'code' => '', 'title' => '330 pF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1121', 'code' => '', 'title' => '470 pF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1122', 'code' => '', 'title' => '680 pF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1123', 'code' => '', 'title' => '1 nF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1124', 'code' => '', 'title' => '2.2 nF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1125', 'code' => '', 'title' => '3.3 nF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1126', 'code' => '', 'title' => '4.7 nF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1127', 'code' => '', 'title' => '6.8 nF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1128', 'code' => '', 'title' => '10 nF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1129', 'code' => '', 'title' => '22 nF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1130', 'code' => '', 'title' => '33 nF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1131', 'code' => '', 'title' => '47 nF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1132', 'code' => '', 'title' => '68 nF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1133', 'code' => '', 'title' => '100 nF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1134', 'code' => '', 'title' => '220 nF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.25', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1135', 'code' => '', 'title' => '470 nF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1136', 'code' => '', 'title' => '680 nF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1137', 'code' => '', 'title' => '1 pF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1138', 'code' => '', 'title' => '2.2 pF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1139', 'code' => '', 'title' => '3.3 pF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1140', 'code' => '', 'title' => '4.7 pF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1141', 'code' => '', 'title' => '6.8 pF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1142', 'code' => '', 'title' => '10 pF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1143', 'code' => '', 'title' => '22 pF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1144', 'code' => '', 'title' => '33 pF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1145', 'code' => '', 'title' => '47 pF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1146', 'code' => '', 'title' => '68 pF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1147', 'code' => '', 'title' => '100 pF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1148', 'code' => '', 'title' => '220 pF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1149', 'code' => '', 'title' => '330 pF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1150', 'code' => '', 'title' => '470 pF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1151', 'code' => '', 'title' => '680 pF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1152', 'code' => '', 'title' => '1 nF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1153', 'code' => '', 'title' => '2.2 nF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1154', 'code' => '', 'title' => '3.3 nF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1155', 'code' => '', 'title' => '4.7 nF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1156', 'code' => '', 'title' => '6.8 nF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1157', 'code' => '', 'title' => '10 nF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1158', 'code' => '', 'title' => '22 nF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1159', 'code' => '', 'title' => '33 nF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1160', 'code' => '', 'title' => '47 nF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1161', 'code' => '', 'title' => '68 nF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1162', 'code' => '', 'title' => '100 nF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1163', 'code' => '', 'title' => '220 nF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '2.25', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1164', 'code' => '', 'title' => '470 nF Capacitor', 'quantity' => '100', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1165', 'code' => '', 'title' => '680 nF Capacitor', 'quantity' => '0', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => 'capacitors.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'), + array('id' => '1166', 'code' => '', 'title' => '1N4001 Rectifier Diode', 'quantity' => '30', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '1.50', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '19'), + array('id' => '1167', 'code' => '', 'title' => '1N4002 Rectifier Diode', 'quantity' => '30', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '1.50', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '19'), + array('id' => '1168', 'code' => '', 'title' => '1N4003 Rectifier Diode', 'quantity' => '30', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '19'), + array('id' => '1169', 'code' => '', 'title' => '1N4005 Rectifier Diode', 'quantity' => '30', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '19'), + array('id' => '1170', 'code' => '', 'title' => '1N4007 Rectifier Diode', 'quantity' => '30', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '19'), + array('id' => '1171', 'code' => '', 'title' => '2V7 Zener Diode', 'quantity' => '20', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '10.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '20'), + array('id' => '1172', 'code' => '', 'title' => '3V3 Zener Diode', 'quantity' => '20', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '10.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '20'), + array('id' => '1173', 'code' => '', 'title' => '4V7 Zener Diode', 'quantity' => '20', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '10.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '20'), + array('id' => '1174', 'code' => '', 'title' => '5V1 Zener Diode', 'quantity' => '20', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '10.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '20'), + array('id' => '1175', 'code' => '', 'title' => '6V8 Zener Diode', 'quantity' => '20', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '10.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '20'), + array('id' => '1176', 'code' => '', 'title' => '8V2 Zener Diode', 'quantity' => '20', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '10.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '20'), + array('id' => '1177', 'code' => '', 'title' => '10V Zener Diode', 'quantity' => '20', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '10.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '20'), + array('id' => '1178', 'code' => '', 'title' => '12V Zener Diode', 'quantity' => '20', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '10.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '20'), + array('id' => '1179', 'code' => '', 'title' => '20V Zener Diode', 'quantity' => '20', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '10.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '20'), + array('id' => '1180', 'code' => '', 'title' => 'Straight 40 pin Male (Black)', 'quantity' => '30', 'specifications' => NULL, 'formFactor' => NULL, 'datasheetURL' => NULL, 'price' => '12.00', 'thumb' => '1656745221.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2022-07-02 07:00:21', 'consumable_type_id' => '22'), + array('id' => '1181', 'code' => '', 'title' => 'Straight 2x40 pin Male (Black)', 'quantity' => '0', 'specifications' => NULL, 'formFactor' => NULL, 'datasheetURL' => NULL, 'price' => '16.00', 'thumb' => '1656744980.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2022-07-02 06:56:20', 'consumable_type_id' => '22'), + array('id' => '1182', 'code' => '', 'title' => 'Straight 40 pin Male (Red)', 'quantity' => '0', 'specifications' => NULL, 'formFactor' => NULL, 'datasheetURL' => NULL, 'price' => '16.00', 'thumb' => '1656745129.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2022-07-02 06:58:49', 'consumable_type_id' => '22'), + array('id' => '1183', 'code' => '', 'title' => 'Straight 40 pin Male (Yellow)', 'quantity' => '0', 'specifications' => NULL, 'formFactor' => NULL, 'datasheetURL' => NULL, 'price' => '16.00', 'thumb' => '1656745143.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2022-07-02 06:59:03', 'consumable_type_id' => '22'), + array('id' => '1184', 'code' => '', 'title' => 'Straight 40 pin Male (Green)', 'quantity' => '0', 'specifications' => NULL, 'formFactor' => NULL, 'datasheetURL' => NULL, 'price' => '16.00', 'thumb' => '1656745155.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2022-07-02 06:59:15', 'consumable_type_id' => '22'), + array('id' => '1185', 'code' => '', 'title' => 'Female 40 pin', 'quantity' => '40', 'specifications' => NULL, 'formFactor' => NULL, 'datasheetURL' => NULL, 'price' => '20.00', 'thumb' => '1656745427.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2022-07-02 07:03:47', 'consumable_type_id' => '22'), + array('id' => '1186', 'code' => '', 'title' => 'Female 2x40 pin', 'quantity' => '20', 'specifications' => NULL, 'formFactor' => NULL, 'datasheetURL' => NULL, 'price' => '45.00', 'thumb' => '1656745449.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2022-07-02 07:04:09', 'consumable_type_id' => '22'), + array('id' => '1187', 'code' => '', 'title' => 'Red (5mm, Diffused) LED', 'quantity' => '100', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '1.75', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '23'), + array('id' => '1188', 'code' => '', 'title' => 'Green (5mm, Diffused) LED', 'quantity' => '100', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '23'), + array('id' => '1189', 'code' => '', 'title' => 'Blue (5mm, Diffused) LED', 'quantity' => '100', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '23'), + array('id' => '1190', 'code' => '', 'title' => 'Yellow (5mm, Diffused) LED', 'quantity' => '100', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '23'), + array('id' => '1191', 'code' => '', 'title' => 'White (5mm, Clean White) LED', 'quantity' => '50', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '2.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '23'), + array('id' => '1192', 'code' => '', 'title' => 'Infrared (5mm) LED', 'quantity' => '0', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '9.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '23'), + array('id' => '1193', 'code' => '', 'title' => 'Ultraviolet (5mm) LED', 'quantity' => '0', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '12.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '23'), + array('id' => '1194', 'code' => '', 'title' => 'Red Single Core Wire', 'quantity' => '25', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '15.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '27'), + array('id' => '1195', 'code' => '', 'title' => 'Black Single Core Wire', 'quantity' => '25', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '15.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '27'), + array('id' => '1196', 'code' => '', 'title' => 'Yellow Single Core Wire', 'quantity' => '25', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '15.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '27'), + array('id' => '1197', 'code' => '', 'title' => 'Red Circuit Wire', 'quantity' => '1', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '10.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '29'), + array('id' => '1198', 'code' => '', 'title' => 'Black Circuit Wire', 'quantity' => '1', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '10.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '29'), + array('id' => '1199', 'code' => '', 'title' => 'White Circuit Wire', 'quantity' => '1', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '10.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '29'), + array('id' => '1200', 'code' => '', 'title' => 'Green Circuit Wire', 'quantity' => '1', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '10.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '29'), + array('id' => '1201', 'code' => '', 'title' => 'Orange Circuit Wire', 'quantity' => '1', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '10.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '29'), + array('id' => '1202', 'code' => '', 'title' => 'Blue Circuit Wire', 'quantity' => '1', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '10.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '29'), + array('id' => '1203', 'code' => '', 'title' => '10 pin IC Base', 'quantity' => '0', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '8.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '25'), + array('id' => '1204', 'code' => '', 'title' => '12 pin IC Base', 'quantity' => '0', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '10.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '25'), + array('id' => '1205', 'code' => '', 'title' => '14 pin IC Base', 'quantity' => '20', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '6.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '25'), + array('id' => '1206', 'code' => '', 'title' => '16 pin IC Base', 'quantity' => '20', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '6.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '25'), + array('id' => '1207', 'code' => '', 'title' => '18 pin IC Base', 'quantity' => '20', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '6.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '25'), + array('id' => '1208', 'code' => '', 'title' => '7400 Logic IC', 'quantity' => '12', 'specifications' => 'Logic ICs', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '38.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '31'), + array('id' => '1209', 'code' => '', 'title' => '7408 Logic IC', 'quantity' => '12', 'specifications' => 'Logic ICs', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '36.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '31'), + array('id' => '1210', 'code' => '', 'title' => '7486 Logic IC', 'quantity' => '0', 'specifications' => 'Logic ICs', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '54.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '31'), + array('id' => '1211', 'code' => '', 'title' => '7404 Logic IC', 'quantity' => '0', 'specifications' => 'Logic ICs', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '36.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '31'), + array('id' => '1212', 'code' => '', 'title' => '7402 Logic IC', 'quantity' => '0', 'specifications' => 'Logic ICs', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '50.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '31'), + array('id' => '1213', 'code' => '', 'title' => '7432 Logic IC', 'quantity' => '0', 'specifications' => 'Logic ICs', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '50.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '31'), + array('id' => '1214', 'code' => '', 'title' => '7410 Logic IC', 'quantity' => '0', 'specifications' => 'Logic ICs', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '85.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '31'), + array('id' => '1215', 'code' => '', 'title' => '7411 Logic IC', 'quantity' => '0', 'specifications' => 'Logic ICs', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '95.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '31'), + array('id' => '1216', 'code' => '', 'title' => '7427 Logic IC', 'quantity' => '0', 'specifications' => 'Logic ICs', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '295.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '31'), + array('id' => '1217', 'code' => '', 'title' => '7447 IC', 'quantity' => '0', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '120.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '32'), + array('id' => '1218', 'code' => '', 'title' => '7491 IC', 'quantity' => '0', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '580.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '32'), + array('id' => '1219', 'code' => '', 'title' => '7476 IC', 'quantity' => '0', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '365.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '32'), + array('id' => '1220', 'code' => '', 'title' => '74138 IC', 'quantity' => '4', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '22.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '32'), + array('id' => '1221', 'code' => '', 'title' => '74139 IC', 'quantity' => '0', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '36.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '32'), + array('id' => '1222', 'code' => '', 'title' => '74157 IC', 'quantity' => '6', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '72.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '32'), + array('id' => '1223', 'code' => '', 'title' => '74244 IC', 'quantity' => '6', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '60.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '32'), + array('id' => '1224', 'code' => '', 'title' => '74245 IC', 'quantity' => '4', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '54.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '32'), + array('id' => '1225', 'code' => '', 'title' => '74273 IC', 'quantity' => '3', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '42.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '32'), + array('id' => '1226', 'code' => '', 'title' => '74283 IC', 'quantity' => '4', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '174.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '32'), + array('id' => '1227', 'code' => '', 'title' => '74173 IC', 'quantity' => '0', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '360.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '32'), + array('id' => '1228', 'code' => '', 'title' => 'NE555 IC', 'quantity' => '7', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '15.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '33'), + array('id' => '1229', 'code' => '', 'title' => 'UA741 IC', 'quantity' => '12', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '15.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '33'), + array('id' => '1230', 'code' => '', 'title' => 'L293 IC', 'quantity' => '0', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '138.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '33'), + array('id' => '1231', 'code' => '', 'title' => 'LM324 IC', 'quantity' => '0', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '30.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '33'), + array('id' => '1232', 'code' => '', 'title' => 'MAX232 IC', 'quantity' => '0', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '50.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '33'), + array('id' => '1233', 'code' => '', 'title' => 'ULN2003 IC', 'quantity' => '0', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '45.00', 'thumb' => '74_logic_ic.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '33'), + array('id' => '1234', 'code' => '', 'title' => '7805 Power Regulator', 'quantity' => '10', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '24.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '34'), + array('id' => '1235', 'code' => '', 'title' => '7806 Power Regulator', 'quantity' => '0', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '20.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '34'), + array('id' => '1236', 'code' => '', 'title' => '7812 Power Regulator', 'quantity' => '10', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '28.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '34'), + array('id' => '1237', 'code' => '', 'title' => 'AMS 1117 3.3V Power Regulator', 'quantity' => '0', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '17.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '34'), + array('id' => '1238', 'code' => '', 'title' => 'AMS 1117 5V Power Regulator', 'quantity' => '0', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '12.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '34'), + array('id' => '1239', 'code' => '', 'title' => '2N2222 Transistor', 'quantity' => '0', 'specifications' => '', 'formFactor' => 'Through Hole', 'datasheetURL' => '', 'price' => '4.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '35'), + array('id' => '1240', 'code' => '', 'title' => 'C828 Transistor', 'quantity' => '0', 'specifications' => '', 'formFactor' => 'Through Hole', 'datasheetURL' => '', 'price' => '5.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '35'), + array('id' => '1241', 'code' => '', 'title' => 'A733 Transistor', 'quantity' => '20', 'specifications' => '', 'formFactor' => 'Through Hole', 'datasheetURL' => '', 'price' => '9.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '35'), + array('id' => '1242', 'code' => '', 'title' => 'BC107 Transistor', 'quantity' => '0', 'specifications' => '', 'formFactor' => 'Through Hole', 'datasheetURL' => '', 'price' => '20.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '35'), + array('id' => '1243', 'code' => '', 'title' => 'BC556 Transistor', 'quantity' => '20', 'specifications' => '', 'formFactor' => 'Through Hole', 'datasheetURL' => '', 'price' => '3.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '35'), + array('id' => '1244', 'code' => '', 'title' => 'S8550 Transistor', 'quantity' => '0', 'specifications' => '', 'formFactor' => 'Through Hole', 'datasheetURL' => '', 'price' => '8.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '35'), + array('id' => '1245', 'code' => '', 'title' => 'S9012 Transistor', 'quantity' => '20', 'specifications' => '', 'formFactor' => 'Through Hole', 'datasheetURL' => '', 'price' => '2.50', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '35'), + array('id' => '1246', 'code' => '', 'title' => 'IRF520N Transistor', 'quantity' => '20', 'specifications' => '', 'formFactor' => 'Through Hole', 'datasheetURL' => '', 'price' => '60.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '35'), + array('id' => '1247', 'code' => '', 'title' => 'IRF9530N Transistor', 'quantity' => '20', 'specifications' => '', 'formFactor' => 'Through Hole', 'datasheetURL' => '', 'price' => '66.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '35'), + array('id' => '1248', 'code' => '', 'title' => '4MHz Crystal Oscillator', 'quantity' => '6', 'specifications' => '', 'formFactor' => 'Through Hole', 'datasheetURL' => '', 'price' => '14.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '36'), + array('id' => '1249', 'code' => '', 'title' => '8MHz Crystal Oscillator', 'quantity' => '0', 'specifications' => '', 'formFactor' => 'Through Hole', 'datasheetURL' => '', 'price' => '14.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '36'), + array('id' => '1250', 'code' => '', 'title' => '12MHz Crystal Oscillator', 'quantity' => '6', 'specifications' => '', 'formFactor' => 'Through Hole', 'datasheetURL' => '', 'price' => '14.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '36'), + array('id' => '1251', 'code' => '', 'title' => '16MHz Crystal Oscillator', 'quantity' => '0', 'specifications' => '', 'formFactor' => 'Through Hole', 'datasheetURL' => '', 'price' => '15.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '36'), + array('id' => '1252', 'code' => '', 'title' => '20MHz Crystal Oscillator', 'quantity' => '0', 'specifications' => '', 'formFactor' => 'Through Hole', 'datasheetURL' => '', 'price' => '14.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '36'), + array('id' => '1253', 'code' => '', 'title' => '32MHz Crystal Oscillator', 'quantity' => '0', 'specifications' => '', 'formFactor' => 'Through Hole', 'datasheetURL' => '', 'price' => '15.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '36'), + array('id' => '1254', 'code' => '', 'title' => '3P DIP Switch', 'quantity' => '20', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '22.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '38'), + array('id' => '1255', 'code' => '', 'title' => '4P DIP Switch', 'quantity' => '20', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '24.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '38'), + array('id' => '1256', 'code' => '', 'title' => '5P DIP Switch', 'quantity' => '20', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '28.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '38'), + array('id' => '1257', 'code' => '', 'title' => '6P DIP Switch', 'quantity' => '20', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '30.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '38'), + array('id' => '1258', 'code' => '', 'title' => '8P DIP Switch', 'quantity' => '20', 'specifications' => '', 'formFactor' => 'DIP, 0.1"', 'datasheetURL' => '', 'price' => '34.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '38'), + array('id' => '1259', 'code' => '', 'title' => 'USB Socket - A Type Female Port', 'quantity' => '0', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '18.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '39'), + array('id' => '1260', 'code' => '', 'title' => 'USB Socket - A Type Male Port', 'quantity' => '0', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '16.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '39'), + array('id' => '1261', 'code' => '', 'title' => 'DC Jack 2.1x5.5mm Port', 'quantity' => '20', 'specifications' => NULL, 'formFactor' => NULL, 'datasheetURL' => NULL, 'price' => '18.00', 'thumb' => '1656746331.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2022-07-02 07:18:51', 'consumable_type_id' => '39'), + array('id' => '1262', 'code' => '', 'title' => 'DC Barrel Socket 2.1x5.5mm Port', 'quantity' => '0', 'specifications' => NULL, 'formFactor' => NULL, 'datasheetURL' => NULL, 'price' => '7.00', 'thumb' => '1656745912.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2022-07-02 07:11:53', 'consumable_type_id' => '39'), + array('id' => '1263', 'code' => '', 'title' => 'Crocodile Clip - Red Port', 'quantity' => '0', 'specifications' => '35mm', 'formFactor' => NULL, 'datasheetURL' => NULL, 'price' => '19.00', 'thumb' => '1656745567.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2022-07-02 07:06:07', 'consumable_type_id' => '39'), + array('id' => '1264', 'code' => '', 'title' => 'Crocodile Clip - Black Port', 'quantity' => '0', 'specifications' => '35mm', 'formFactor' => NULL, 'datasheetURL' => NULL, 'price' => '19.00', 'thumb' => '1656745594.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2022-07-02 07:06:34', 'consumable_type_id' => '39'), + array('id' => '1265', 'code' => '', 'title' => '500 Ω Trimpot', 'quantity' => '15', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '15.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '40'), + array('id' => '1266', 'code' => '', 'title' => '1 kΩ Trimpot', 'quantity' => '15', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '15.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '40'), + array('id' => '1267', 'code' => '', 'title' => '2 kΩ Trimpot', 'quantity' => '15', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '15.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '40'), + array('id' => '1268', 'code' => '', 'title' => '5 kΩ Trimpot', 'quantity' => '15', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '15.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '40'), + array('id' => '1269', 'code' => '', 'title' => '10 kΩ Trimpot', 'quantity' => '15', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '15.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '40'), + array('id' => '1270', 'code' => '', 'title' => '20 kΩ Trimpot', 'quantity' => '15', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '15.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '40'), + array('id' => '1271', 'code' => '', 'title' => '50 kΩ Trimpot', 'quantity' => '15', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '15.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '40'), + array('id' => '1272', 'code' => '', 'title' => '100 kΩ Trimpot', 'quantity' => '15', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '15.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '40'), + array('id' => '1273', 'code' => '', 'title' => '220 kΩ Trimpot', 'quantity' => '15', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '15.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '40'), + array('id' => '1274', 'code' => '', 'title' => '500 kΩ Trimpot', 'quantity' => '15', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '15.00', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '40') + + ]; + + /** + * Run the database seeds. + * + * @return void + */ + public function run() + { + foreach ($this->data as $index => $setting) { + $result = DB::table('consumable_items')->insert($setting); + + if (!$result) { + $this->command->info("Insert failed at record $index."); + return; + } + } + + $this->command->info('Inserted ' . count($this->data) . ' records to consumable_items table'); + } +} \ No newline at end of file diff --git a/database/seeders/ConsumableTypeSeeder.php b/database/seeders/ConsumableTypeSeeder.php new file mode 100755 index 00000000..e51291b9 --- /dev/null +++ b/database/seeders/ConsumableTypeSeeder.php @@ -0,0 +1,62 @@ + '11', 'parent_id' => NULL, 'code' => '', 'title' => 'Resistors', 'subtitle' => '', 'description' => 'Various types of resistors', 'thumb' => NULL, 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2021-07-04 15:21:03'), + array('id' => '12', 'parent_id' => '11', 'code' => '', 'title' => 'Through Hole Resistors (1/4W)', 'subtitle' => NULL, 'description' => 'Through-hole resistors', 'thumb' => '1656727479.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:04:53'), + array('id' => '13', 'parent_id' => '11', 'code' => '', 'title' => 'SMD Resistors (1206)', 'subtitle' => NULL, 'description' => 'Surface-mount Resistors, with the form factor of 1206', 'thumb' => '1656727431.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:03:51'), + array('id' => '14', 'parent_id' => NULL, 'code' => '', 'title' => 'Capacitors', 'subtitle' => '', 'description' => 'Various types of capacitors', 'thumb' => NULL, 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2021-07-04 15:21:03'), + array('id' => '15', 'parent_id' => '14', 'code' => '', 'title' => 'Electrolytic Capacitors (16V)', 'subtitle' => NULL, 'description' => '16V Electrolyte capacitors', 'thumb' => '1656727560.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:06:00'), + array('id' => '16', 'parent_id' => '14', 'code' => '', 'title' => 'Ceramic Capacitors', 'subtitle' => NULL, 'description' => 'Ceramic capacitors of various values', 'thumb' => '1656727604.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:06:44'), + array('id' => '17', 'parent_id' => '14', 'code' => '', 'title' => 'SMD Capacitors (1206)', 'subtitle' => NULL, 'description' => 'Surface-mount capacitors of the form factor 1206', 'thumb' => '1656727698.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:08:18'), + array('id' => '18', 'parent_id' => NULL, 'code' => '', 'title' => 'Diodes', 'subtitle' => '', 'description' => 'Various types of diodes', 'thumb' => NULL, 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2021-07-04 15:21:03'), + array('id' => '19', 'parent_id' => '18', 'code' => '', 'title' => 'Rectifier Diodes', 'subtitle' => NULL, 'description' => 'Various values of Rectifier Diodes', 'thumb' => '1656727743.png', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:09:03'), + array('id' => '20', 'parent_id' => '18', 'code' => '', 'title' => 'Zener Diodes', 'subtitle' => NULL, 'description' => 'Various values of Zener Diodes', 'thumb' => '1656727802.png', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:10:02'), + array('id' => '22', 'parent_id' => '43', 'code' => '', 'title' => 'Headers', 'subtitle' => NULL, 'description' => 'a form of electrical connector', 'thumb' => '1656745253.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 07:00:53'), + array('id' => '23', 'parent_id' => NULL, 'code' => '', 'title' => 'LEDs', 'subtitle' => NULL, 'description' => 'Light Emitting Diodes', 'thumb' => '1656727926.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:12:06'), + array('id' => '25', 'parent_id' => NULL, 'code' => '', 'title' => 'IC Bases', 'subtitle' => NULL, 'description' => 'Allows the user to connect the ICs with the circuits', 'thumb' => '1656728124.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:15:24'), + array('id' => '26', 'parent_id' => NULL, 'code' => '', 'title' => 'Circuit Wires', 'subtitle' => NULL, 'description' => 'A type of conductor, a material that conducts electricity', 'thumb' => '1656728217.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:16:58'), + array('id' => '27', 'parent_id' => '26', 'code' => '', 'title' => 'Single-core Wires', 'subtitle' => NULL, 'description' => 'Wires that have a single core', 'thumb' => '1656728275.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:17:55'), + array('id' => '28', 'parent_id' => '26', 'code' => '', 'title' => 'Wires (14/0.30mm)', 'subtitle' => 'Auto wire', 'description' => 'Wires that have 14 cores and a cross-area of 0.30mm^2', 'thumb' => '1656728356.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:19:16'), + array('id' => '29', 'parent_id' => '26', 'code' => '', 'title' => 'Circuit Wires', 'subtitle' => NULL, 'description' => 'An electrical wire is a type of conductor, which is a material that conducts electricity', 'thumb' => '1656728419.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:20:19'), + array('id' => '30', 'parent_id' => NULL, 'code' => '', 'title' => 'ICs', 'subtitle' => 'Integrated Circuits', 'description' => 'An integrated circuit (IC), also called a microelectronic circuit, microchip, or chip, is an assembly of electronic components, fabricated as a single unit, in which miniaturized active devices (e.g., transistors and diodes) and passive devices (e.g., capacitors and resistors)', 'thumb' => '1656728542.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:22:22'), + array('id' => '31', 'parent_id' => '30', 'code' => '', 'title' => 'Logic ICs', 'subtitle' => NULL, 'description' => 'Logic Integrated Circuits (Logic gates)', 'thumb' => NULL, 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:22:44'), + array('id' => '32', 'parent_id' => '30', 'code' => '', 'title' => '74 Series ICs', 'subtitle' => '74xxx Series ICs', 'description' => '74xxx Series Integrated Circuits', 'thumb' => NULL, 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:23:23'), + array('id' => '33', 'parent_id' => '30', 'code' => '', 'title' => 'Other ICs', 'subtitle' => NULL, 'description' => 'Integrated Circuits', 'thumb' => NULL, 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:23:36'), + array('id' => '34', 'parent_id' => NULL, 'code' => '', 'title' => 'Voltage Regulators', 'subtitle' => NULL, 'description' => 'Voltage Regulators', 'thumb' => '1656728672.png', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:24:32'), + array('id' => '35', 'parent_id' => NULL, 'code' => '', 'title' => 'Transistors', 'subtitle' => NULL, 'description' => 'Various types of transistors', 'thumb' => '1656728778.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:26:18'), + array('id' => '36', 'parent_id' => NULL, 'code' => '', 'title' => 'Crystal Oscillators', 'subtitle' => NULL, 'description' => 'A crystal oscillator is an electronic oscillator that makes use of crystal as a frequency selective element to obtain an inverse piezoelectric effect', 'thumb' => '1656728855.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:27:36'), + array('id' => '37', 'parent_id' => NULL, 'code' => '', 'title' => 'Switches', 'subtitle' => NULL, 'description' => 'Various kinds of switches', 'thumb' => '1656728991.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:29:51'), + array('id' => '38', 'parent_id' => '37', 'code' => '', 'title' => 'DIP Switches', 'subtitle' => 'Dual Inline Packaged switches', 'description' => 'Dual Inline Packaged switches', 'thumb' => '1656729066.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:31:07'), + array('id' => '39', 'parent_id' => NULL, 'code' => '', 'title' => 'Ports', 'subtitle' => NULL, 'description' => 'Different kinds of ports to interconnect devices', 'thumb' => '1656745872.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 07:11:12'), + array('id' => '40', 'parent_id' => '11', 'code' => '', 'title' => 'Trimmer Potentiometers', 'subtitle' => 'Trim Pots', 'description' => 'Variable Resistors', 'thumb' => '1656743980.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:34:42'), + array('id' => '41', 'parent_id' => '43', 'code' => '', 'title' => 'PCB Terminals', 'subtitle' => NULL, 'description' => 'PCB terminal blocks are modular, insulated devices that mount on printed circuit boards (PCBs) and secure two or more wires together', 'thumb' => '1656729359.jpg', 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:38:55'), + array('id' => '42', 'parent_id' => '43', 'code' => '', 'title' => 'Screw Terminals', 'subtitle' => NULL, 'description' => 'Screw connectors or screw terminals are commonly used concurrently with ring connectors, rectangular connectors, spade connectors, or bare wire', 'thumb' => NULL, 'created_at' => '2021-07-04 15:20:56', 'updated_at' => '2022-07-02 02:38:40'), + array('id' => '43', 'parent_id' => NULL, 'code' => '', 'title' => 'Connectors', 'subtitle' => NULL, 'description' => 'Different types of connectors used to connect electronic components together', 'thumb' => NULL, 'created_at' => '2022-07-02 02:38:23', 'updated_at' => '2022-07-02 02:38:23'), + array('id' => '44', 'parent_id' => '37', 'code' => '', 'title' => 'Toggle Switches', 'subtitle' => NULL, 'description' => 'A toggle switch is a type of electrical switch that is actuated by moving a lever back and forth to open or close an electrical circuit', 'thumb' => '1656730311.jpg', 'created_at' => '2022-07-02 02:51:51', 'updated_at' => '2022-07-02 02:51:51') + ]; + + /** + * Run the database seeds. + * + * @return void + */ + public function run() + { + foreach ($this->data as $index => $value) { + $result = DB::table('consumable_types')->insert($value); + + if (!$result) { + $this->command->info("Insert failed at record $index."); + return; + } + } + $this->command->info('Inserted ' . count($this->data) . ' records to consumable_types table'); + } +} diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php old mode 100644 new mode 100755 index 86a1b949..58bab5e4 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -2,9 +2,10 @@ namespace Database\Seeders; -use Database\Seeders\Traits\TruncateTable; -use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Seeder; +use Torann\GeoIP\Location; +use Illuminate\Database\Eloquent\Model; +use Database\Seeders\Traits\TruncateTable; /** * Class DatabaseSeeder. @@ -32,6 +33,15 @@ public function run() $this->call(EquipmentItemSeeder::class); $this->call(ComponentTypeSeeder::class); $this->call(ComponentItemSeeder::class); + $this->call(ConsumableTypeSeeder::class); + $this->call(ConsumableItemSeeder::class); + $this->call(RawMaterialsSeeder::class); + $this->call(MachinesSeeder::class); + $this->call(JobRequestsSeeder::class); + $this->call(LocationsSeeder::class); + $this->call(ItemLocationsSeeder::class); + $this->call(StationsSeeder::class); + $this->call(ReservationsSeeder::class); Model::reguard(); } diff --git a/database/seeders/EquipmentItemSeeder.php b/database/seeders/EquipmentItemSeeder.php old mode 100644 new mode 100755 index 0e7198ba..65a99078 --- a/database/seeders/EquipmentItemSeeder.php +++ b/database/seeders/EquipmentItemSeeder.php @@ -8,60 +8,209 @@ class EquipmentItemSeeder extends Seeder { protected $data = [ - array('id' => '1000', 'code' => '', 'title' => 'Flathead Screwdriver 8x150', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Flathead Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '300.00', 'width' => '4.00', 'length' => '28.00', 'height' => '4.00', 'weight' => '150.00', 'thumb' => '1629197752.jpg', 'created_at' => '2021-08-17 10:55:53', 'updated_at' => '2021-08-22 12:19:07', 'equipment_type_id' => '17'), - array('id' => '1001', 'code' => '', 'title' => 'Flathead Screwdriver 6x100', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Flathead Screwdriver 6x100', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '250.00', 'width' => '4.00', 'length' => '22.00', 'height' => '4.00', 'weight' => '90.00', 'thumb' => '1629198096.jpg', 'created_at' => '2021-08-17 11:01:36', 'updated_at' => '2021-08-22 12:19:37', 'equipment_type_id' => '17'), - array('id' => '1002', 'code' => '', 'title' => 'Flathead Screwdriver 5x75', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Flathead Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '200.00', 'width' => '3.00', 'length' => '18.00', 'height' => '3.00', 'weight' => '60.00', 'thumb' => '1629198157.jpg', 'created_at' => '2021-08-17 11:02:37', 'updated_at' => '2021-08-22 12:19:53', 'equipment_type_id' => '17'), - array('id' => '1003', 'code' => '', 'title' => 'Phillips head Screwdriver PH3x150', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Phillips head Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '300.00', 'width' => '4.00', 'length' => '28.00', 'height' => '4.00', 'weight' => '150.00', 'thumb' => '1629198303.jpg', 'created_at' => '2021-08-17 11:05:03', 'updated_at' => '2021-08-22 12:20:12', 'equipment_type_id' => '17'), - array('id' => '1004', 'code' => '', 'title' => 'Phillips head Screwdriver PH2x100', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Phillips head Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '250.00', 'width' => '4.00', 'length' => '22.00', 'height' => '4.00', 'weight' => '90.00', 'thumb' => '1629198371.jpg', 'created_at' => '2021-08-17 11:06:11', 'updated_at' => '2021-08-22 12:20:17', 'equipment_type_id' => '17'), - array('id' => '1005', 'code' => '', 'title' => 'Phillips head Screwdriver PH1x75', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Phillips head Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '200.00', 'width' => '3.00', 'length' => '18.00', 'height' => '3.00', 'weight' => '60.00', 'thumb' => '1629198418.jpg', 'created_at' => '2021-08-17 11:06:58', 'updated_at' => '2021-08-22 12:20:22', 'equipment_type_id' => '17'), - array('id' => '1006', 'code' => '', 'title' => 'Flathead Screwdriver 6x38', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Flathead Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '100.00', 'width' => '4.00', 'length' => '11.00', 'height' => '4.00', 'weight' => '50.00', 'thumb' => '1629198526.jpg', 'created_at' => '2021-08-17 11:08:46', 'updated_at' => '2021-08-22 12:20:42', 'equipment_type_id' => '17'), - array('id' => '1007', 'code' => '', 'title' => 'Phillips head Screwdriver PH2x38', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Phillips head Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '100.00', 'width' => '4.00', 'length' => '11.00', 'height' => '4.00', 'weight' => '50.00', 'thumb' => '1629198571.jpg', 'created_at' => '2021-08-17 11:09:31', 'updated_at' => '2021-08-22 12:20:46', 'equipment_type_id' => '17'), - array('id' => '1008', 'code' => '', 'title' => 'Screw Bit Holder', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Screw Bit Holder', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '200.00', 'width' => '4.00', 'length' => '18.00', 'height' => '4.00', 'weight' => '120.00', 'thumb' => '1629198659.jpg', 'created_at' => '2021-08-17 11:11:00', 'updated_at' => '2021-08-22 12:21:03', 'equipment_type_id' => '17'), - array('id' => '1009', 'code' => '', 'title' => 'Flathead Precision Screwdriver 3x50', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Flathead Precision Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '150.00', 'width' => '2.00', 'length' => '14.00', 'height' => '2.00', 'weight' => '15.00', 'thumb' => '1629198802.jpg', 'created_at' => '2021-08-17 11:13:22', 'updated_at' => '2021-08-22 12:21:27', 'equipment_type_id' => '17'), - array('id' => '1010', 'code' => '', 'title' => 'Flathead Precision Screwdriver 2.5x50', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Flathead Precision Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '150.00', 'width' => '2.00', 'length' => '14.00', 'height' => '2.00', 'weight' => '15.00', 'thumb' => '1629198869.jpg', 'created_at' => '2021-08-17 11:14:30', 'updated_at' => '2021-08-22 12:21:32', 'equipment_type_id' => '17'), - array('id' => '1011', 'code' => '', 'title' => 'Flathead Precision Screwdriver 2x50', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Flathead Precision Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '150.00', 'width' => '2.00', 'length' => '14.00', 'height' => '2.00', 'weight' => '15.00', 'thumb' => '1629198912.jpg', 'created_at' => '2021-08-17 11:15:13', 'updated_at' => '2021-08-22 12:21:36', 'equipment_type_id' => '17'), - array('id' => '1012', 'code' => '', 'title' => 'Phillips head Screwdriver PH0x50', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Phillips head Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '150.00', 'width' => '2.00', 'length' => '14.00', 'height' => '2.00', 'weight' => '15.00', 'thumb' => '1629199000.jpg', 'created_at' => '2021-08-17 11:16:40', 'updated_at' => '2021-08-22 12:21:41', 'equipment_type_id' => '17'), - array('id' => '1013', 'code' => '', 'title' => 'Phillips head Screwdriver PH00x50', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Phillips head Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '150.00', 'width' => '2.00', 'length' => '14.00', 'height' => '2.00', 'weight' => '15.00', 'thumb' => '1629199040.jpg', 'created_at' => '2021-08-17 11:17:20', 'updated_at' => '2021-08-22 12:21:45', 'equipment_type_id' => '17'), - array('id' => '1014', 'code' => '', 'title' => 'Torx Precision Screwdriver T6x50', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Torx Precision Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '150.00', 'width' => '2.00', 'length' => '14.00', 'height' => '2.00', 'weight' => '15.00', 'thumb' => '1629199113.jpg', 'created_at' => '2021-08-17 11:18:33', 'updated_at' => '2021-08-22 12:21:53', 'equipment_type_id' => '17'), - array('id' => '1015', 'code' => '', 'title' => 'Torx Precision Screwdriver T8x50', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Torx Precision Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '150.00', 'width' => '2.00', 'length' => '14.00', 'height' => '2.00', 'weight' => '15.00', 'thumb' => '1629199145.jpg', 'created_at' => '2021-08-17 11:19:05', 'updated_at' => '2021-08-22 12:21:56', 'equipment_type_id' => '17'), - array('id' => '1016', 'code' => '', 'title' => 'Torx Precision Screwdriver T10x50', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Torx Precision Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '150.00', 'width' => '2.00', 'length' => '14.00', 'height' => '2.00', 'weight' => '15.00', 'thumb' => '1629199178.jpg', 'created_at' => '2021-08-17 11:19:38', 'updated_at' => '2021-08-22 12:22:20', 'equipment_type_id' => '17'), - array('id' => '1017', 'code' => '', 'title' => '1/4 Bits Set', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => '1/4 Bits Set Flathead 4,5,6 Phillips head PH0, PH1, PH2, PZ1, PZ2 Torx T20, T25, T30 Hex 2, 3, 4, 5, 67', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '300.00', 'width' => '7.00', 'length' => '1.50', 'height' => '7.00', 'weight' => '0.00', 'thumb' => '1629199501.jpg', 'created_at' => '2021-08-17 11:25:01', 'updated_at' => '2021-08-22 12:22:51', 'equipment_type_id' => '17'), - array('id' => '1018', 'code' => '', 'title' => '1/4 Socket Set', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => '1/4 Sockets Sockets: 6, 7, 8, 9, 10', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '300.00', 'width' => '7.00', 'length' => '1.50', 'height' => '5.00', 'weight' => '0.00', 'thumb' => '1629199664.jpg', 'created_at' => '2021-08-17 11:27:45', 'updated_at' => '2021-08-22 12:22:56', 'equipment_type_id' => '24'), - array('id' => '1019', 'code' => '', 'title' => 'Megnetizer and Demagnetizer', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'This can be used to magnetize or de-magnetize the screwdriver heads', 'instructions' => 'https://www.youtube.com/watch?v=Z0gAdLvlrHA', 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '250.00', 'width' => '2.00', 'length' => '2.00', 'height' => '5.00', 'weight' => '0.00', 'thumb' => '1629199801.jpg', 'created_at' => '2021-08-17 11:30:01', 'updated_at' => '2021-08-22 12:23:11', 'equipment_type_id' => '17'), - array('id' => '1020', 'code' => '', 'title' => 'Flat Steel File', 'brand' => 'Juneng', 'productCode' => 'JN100405', 'quantity' => '1', 'specifications' => '8"', 'description' => 'Flat Steel File', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '690.00', 'width' => '4.00', 'length' => '31.00', 'height' => '4.00', 'weight' => '200.00', 'thumb' => '1629630306.jpg', 'created_at' => '2021-08-22 11:05:06', 'updated_at' => '2021-08-22 11:05:06', 'equipment_type_id' => '25'), - array('id' => '1021', 'code' => '', 'title' => 'Half Round Steel File', 'brand' => 'Juneng', 'productCode' => 'JN100404', 'quantity' => '1', 'specifications' => 'Half Round Steel File', 'description' => 'Half Round Steel File', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '725.00', 'width' => '4.00', 'length' => '31.00', 'height' => '4.00', 'weight' => '200.00', 'thumb' => '1629630519.jpg', 'created_at' => '2021-08-22 11:08:39', 'updated_at' => '2021-08-22 11:08:50', 'equipment_type_id' => '25'), - array('id' => '1022', 'code' => '', 'title' => 'Wire Cutter', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '2', 'specifications' => NULL, 'description' => 'Wire Cutter, this can be used to cut the small circuit wires', 'instructions' => NULL, 'isElectrical' => '1', 'powerRating' => NULL, 'price' => '325.00', 'width' => '6.50', 'length' => '12.00', 'height' => '1.50', 'weight' => '65.00', 'thumb' => '1629630731.jpg', 'created_at' => '2021-08-22 11:12:11', 'updated_at' => '2021-08-22 11:12:11', 'equipment_type_id' => '22'), - array('id' => '1023', 'code' => '', 'title' => 'Double Open Spanner Wrenches Set', 'brand' => 'Ingco', 'productCode' => 'HKSPA2088', 'quantity' => '1', 'specifications' => 'Sizes: 6-7, 8-9, 10-11, 12-13, 14-15, 16-17, 18-19, 20-22', 'description' => 'Double Open End Spanner Set', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '2174.00', 'width' => '22.00', 'length' => '20.00', 'height' => '5.00', 'weight' => '865.00', 'thumb' => '1629631989.jpg', 'created_at' => '2021-08-22 11:33:09', 'updated_at' => '2021-08-22 11:33:46', 'equipment_type_id' => '19'), - array('id' => '1024', 'code' => '', 'title' => 'Hand Riveter', 'brand' => 'Jinma', 'productCode' => 'JM-1001', 'quantity' => '1', 'specifications' => 'Nozzles: 2,4 3,2 4,0 4,8', 'description' => '9.5" 240mm Hand Riveter', 'instructions' => 'Plug the rivet, Relax the grip handle, plug in the rivet head, Clamp the grip handle until the rivet pole is broken', 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '620.00', 'width' => '9.00', 'length' => '25.00', 'height' => '5.00', 'weight' => '450.00', 'thumb' => '1629632266.jpg', 'created_at' => '2021-08-22 11:37:47', 'updated_at' => '2021-08-22 11:38:32', 'equipment_type_id' => '11'), - array('id' => '1025', 'code' => '', 'title' => 'Respiratory Mask', 'brand' => 'Ingco', 'productCode' => 'HRS02', 'quantity' => '1', 'specifications' => 'Half face twin cartridge respirator, Industrial/trade quality, Protection against Harmful material with volume concentration <0.1%', 'description' => 'Can be used as a mask when working with chemicals and dust', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '2610.00', 'width' => '18.00', 'length' => '10.00', 'height' => '12.00', 'weight' => '435.00', 'thumb' => '1629632619.jpg', 'created_at' => '2021-08-22 11:43:40', 'updated_at' => '2021-08-22 11:43:57', 'equipment_type_id' => '13'), - array('id' => '1026', 'code' => '', 'title' => 'Measuring Tape', 'brand' => 'Ingco', 'productCode' => 'HSMT08052', 'quantity' => '2', 'specifications' => 'Length: 5m, Tape width: 19mm', 'description' => 'Measuring tape', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '475.00', 'width' => '9.50', 'length' => '7.50', 'height' => '4.00', 'weight' => '200.00', 'thumb' => '1629632813.png', 'created_at' => '2021-08-22 11:46:53', 'updated_at' => '2021-08-22 11:46:53', 'equipment_type_id' => '15'), - array('id' => '1027', 'code' => '', 'title' => 'Carpenter Square', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '2', 'specifications' => NULL, 'description' => 'Used in carpentry, to lay out structures that are square', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '250.00', 'width' => '30.00', 'length' => '13.00', 'height' => '1.50', 'weight' => '100.00', 'thumb' => '1629632925.jpg', 'created_at' => '2021-08-22 11:48:45', 'updated_at' => '2021-08-22 11:48:45', 'equipment_type_id' => '15'), - array('id' => '1028', 'code' => '', 'title' => 'Spirit Level', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '1', 'specifications' => '45cm', 'description' => 'A Spirit Level is a tool used to indicate how parallel (level) or perpendicular (plumb) a surface is relative to the earth', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '775.00', 'width' => '2.00', 'length' => '45.00', 'height' => '5.00', 'weight' => '160.00', 'thumb' => '1629633015.jpg', 'created_at' => '2021-08-22 11:50:16', 'updated_at' => '2021-08-22 11:50:16', 'equipment_type_id' => '15'), - array('id' => '1029', 'code' => '', 'title' => 'Digital Caliper', 'brand' => 'Ingco', 'productCode' => 'HDCD01150', 'quantity' => '1', 'specifications' => 'Comes with a plastic box and one extra battery, Range: 0-150mm, Reading: 0.01mm, Metric and Inch', 'description' => 'A caliper is a device used to measure the dimensions of an object', 'instructions' => 'Please read the instruction manual in the box for details', 'isElectrical' => '1', 'powerRating' => NULL, 'price' => '4180.00', 'width' => '6.00', 'length' => '25.00', 'height' => '2.50', 'weight' => '300.00', 'thumb' => '1629633245.png', 'created_at' => '2021-08-22 11:54:05', 'updated_at' => '2021-08-22 11:56:00', 'equipment_type_id' => '15'), - array('id' => '1030', 'code' => '', 'title' => 'Paper Cutter', 'brand' => 'Ingco', 'productCode' => 'HKNS16618', 'quantity' => '2', 'specifications' => '18x100mm', 'description' => 'Snap-off Blade Knife', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '300.00', 'width' => '4.00', 'length' => '18.00', 'height' => '2.50', 'weight' => '85.00', 'thumb' => '1629633529.png', 'created_at' => '2021-08-22 11:58:50', 'updated_at' => '2021-08-22 11:58:50', 'equipment_type_id' => '22'), - array('id' => '1031', 'code' => '', 'title' => 'Hole Saw Set', 'brand' => 'BOSHICHI', 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'Support only with wood and plastic materials, Induction Hardened Steel, Sizes: 2-1/8", 2", 1-1/2", 1-1/4"', 'description' => 'Used to drill large holes', 'instructions' => 'Need to set the saw blade into the mandred using the hex key before use. Use the drill at medium speed.', 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '450.00', 'width' => '10.00', 'length' => '14.00', 'height' => '3.50', 'weight' => '190.00', 'thumb' => '1629633859.jpg', 'created_at' => '2021-08-22 12:04:19', 'updated_at' => '2021-08-22 12:05:28', 'equipment_type_id' => '22'), - array('id' => '1032', 'code' => '', 'title' => 'Wire Stripper', 'brand' => 'Ingco', 'productCode' => 'HWSP15608', 'quantity' => '1', 'specifications' => '0.5-6mm range', 'description' => 'Wire Stripper, can be used to remove the rubber part from the copper wires.', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '1200.00', 'width' => '9.00', 'length' => '18.50', 'height' => '2.50', 'weight' => '225.00', 'thumb' => '1629683617.jpg', 'created_at' => '2021-08-23 01:53:37', 'updated_at' => '2021-08-23 01:53:37', 'equipment_type_id' => '11'), - array('id' => '1033', 'code' => '', 'title' => 'Wire Stripper with Crimping', 'brand' => 'Ingco', 'productCode' => 'HWSP101', 'quantity' => '1', 'specifications' => '10" / 250mm', 'description' => 'Can be used to strip the wires and do crimping and cutting the wires', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '1100.00', 'width' => '7.00', 'length' => '26.00', 'height' => '2.50', 'weight' => '325.00', 'thumb' => '1629683896.jpg', 'created_at' => '2021-08-23 01:58:17', 'updated_at' => '2021-08-23 01:58:17', 'equipment_type_id' => '11'), - array('id' => '1034', 'code' => '', 'title' => 'Combination Plier', 'brand' => 'Ingco', 'productCode' => 'HCP2208', 'quantity' => '1', 'specifications' => '200mm / 8"', 'description' => 'Combination Plier', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '850.00', 'width' => '7.00', 'length' => '20.50', 'height' => '3.50', 'weight' => '325.00', 'thumb' => '1629684152.jpg', 'created_at' => '2021-08-23 02:02:33', 'updated_at' => '2021-08-23 02:05:29', 'equipment_type_id' => '18'), - array('id' => '1035', 'code' => '', 'title' => 'Long Nose Plier', 'brand' => 'Ingco', 'productCode' => 'HLNP08168', 'quantity' => '2', 'specifications' => '160mm / 6"', 'description' => 'Long Nose Plier', 'instructions' => NULL, 'isElectrical' => '1', 'powerRating' => NULL, 'price' => '600.00', 'width' => '6.00', 'length' => '17.00', 'height' => '2.00', 'weight' => '120.00', 'thumb' => '1629684307.jpg', 'created_at' => '2021-08-23 02:05:08', 'updated_at' => '2021-08-23 02:05:08', 'equipment_type_id' => '18'), - array('id' => '1036', 'code' => '', 'title' => 'Diagonal Cutting Plier', 'brand' => 'Ingco', 'productCode' => 'HDCP08168', 'quantity' => '1', 'specifications' => '160mm / 6"', 'description' => 'Diagonal Cutting Plier', 'instructions' => NULL, 'isElectrical' => '1', 'powerRating' => NULL, 'price' => '600.00', 'width' => '6.00', 'length' => '17.00', 'height' => '2.00', 'weight' => '200.00', 'thumb' => '1629684517.jpg', 'created_at' => '2021-08-23 02:08:37', 'updated_at' => '2021-08-23 02:08:37', 'equipment_type_id' => '18'), - array('id' => '1037', 'code' => '', 'title' => '6 pcs Precision Screw Driver Set', 'brand' => 'Ingco', 'productCode' => 'HKSD0618', 'quantity' => '1', 'specifications' => 'Comes in an enclosure box, SL2.0, SL2.5, SL 3.0, PH000, PH00, PH0', 'description' => 'Precision Screwdriver Set', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '700.00', 'width' => '9.00', 'length' => '15.00', 'height' => '2.50', 'weight' => '145.00', 'thumb' => '1629684973.jpg', 'created_at' => '2021-08-23 02:16:14', 'updated_at' => '2021-08-23 02:16:14', 'equipment_type_id' => '17'), - array('id' => '1038', 'code' => '', 'title' => 'Hex Key Set', 'brand' => 'Ingco', 'productCode' => 'HHK11091', 'quantity' => '1', 'specifications' => '9pcs, Sizes: 1.5mm, 2.0mm, 2.5mm, 3.0mm, 4.0mm, 5.0mm, 6.0mm, 8.0mm, 10.0mm,', 'description' => 'Hex / Allen Key Set, Long Arm', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '1100.00', 'width' => '7.50', 'length' => '18.00', 'height' => '3.00', 'weight' => '360.00', 'thumb' => '1629685225.jpg', 'created_at' => '2021-08-23 02:20:25', 'updated_at' => '2021-08-23 02:20:25', 'equipment_type_id' => '17'), - array('id' => '1039', 'code' => '', 'title' => 'Torx Key Set', 'brand' => 'TOTAL', 'productCode' => 'THT106392', 'quantity' => '1', 'specifications' => 'T10, T15, T20, T25, T27, T30, T40, T45, T50', 'description' => '9 Pcs Torx Key Set', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '1100.00', 'width' => '7.50', 'length' => '18.00', 'height' => '3.00', 'weight' => '340.00', 'thumb' => '1629685472.jpg', 'created_at' => '2021-08-23 02:24:32', 'updated_at' => '2021-08-23 02:24:55', 'equipment_type_id' => '17'), - array('id' => '1040', 'code' => '', 'title' => 'Adjustable Wrench', 'brand' => 'Ingco', 'productCode' => 'HADW131088', 'quantity' => '1', 'specifications' => '200mm handle, Max 30mm Jaw', 'description' => 'Adjustable Wrench', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '950.00', 'width' => '7.00', 'length' => '21.50', 'height' => '2.50', 'weight' => '300.00', 'thumb' => '1629693477.png', 'created_at' => '2021-08-23 04:37:58', 'updated_at' => '2021-08-23 04:38:33', 'equipment_type_id' => '19'), - array('id' => '1041', 'code' => '', 'title' => 'Trigeminal socket wrench', 'brand' => 'Ingco', 'productCode' => 'HYW081012', 'quantity' => '1', 'specifications' => 'Socket Sizes: 8, 10, 12', 'description' => 'Y Type Socket Wrench', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '500.00', 'width' => '25.00', 'length' => '21.00', 'height' => '2.00', 'weight' => '265.00', 'thumb' => '1629693629.jpg', 'created_at' => '2021-08-23 04:40:29', 'updated_at' => '2021-08-23 04:41:10', 'equipment_type_id' => '19'), - array('id' => '1042', 'code' => '', 'title' => 'Wood Chisel', 'brand' => 'Ingco', 'productCode' => 'HWC0819', 'quantity' => '1', 'specifications' => '19mm (3/4")', 'description' => 'Wood Chisel', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '580.00', 'width' => '4.50', 'length' => '27.00', 'height' => '4.50', 'weight' => '200.00', 'thumb' => '1629693911.jpg', 'created_at' => '2021-08-23 04:45:11', 'updated_at' => '2021-08-23 04:45:11', 'equipment_type_id' => '22'), - array('id' => '1043', 'code' => '', 'title' => 'Claw Hammer', 'brand' => 'Ingco', 'productCode' => 'HCH880227', 'quantity' => '1', 'specifications' => 'Fiberglass Handle, Drop Forged', 'description' => 'Claw Hammer', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '800.00', 'width' => '14.00', 'length' => '33.00', 'height' => '3.00', 'weight' => '650.00', 'thumb' => '1629694153.jpg', 'created_at' => '2021-08-23 04:49:13', 'updated_at' => '2021-08-23 04:49:13', 'equipment_type_id' => '23'), - array('id' => '1044', 'code' => '', 'title' => 'Hacksaw', 'brand' => 'Ingco', 'productCode' => 'HHF3028', 'quantity' => '1', 'specifications' => '12" / 300mm HSS Blade', 'description' => 'A saw with a narrow fine-toothed blade set in a frame used especially for cutting metal.', 'instructions' => NULL, 'isElectrical' => '1', 'powerRating' => NULL, 'price' => '600.00', 'width' => '14.00', 'length' => '45.00', 'height' => '2.50', 'weight' => '370.00', 'thumb' => '1629694329.png', 'created_at' => '2021-08-23 04:52:09', 'updated_at' => '2021-08-23 04:52:09', 'equipment_type_id' => '22'), - array('id' => '1045', 'code' => '', 'title' => 'G Clamp', 'brand' => 'Ingco', 'productCode' => 'HGC0106', 'quantity' => '2', 'specifications' => '6" Clamping Space', 'description' => 'G-clamp is a type of clamp device typically used to hold a wood or metal workpiece, and often used in, but are not limited to, carpentry and welding', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '1200.00', 'width' => '16.00', 'length' => '26.00', 'height' => '3.50', 'weight' => '1500.00', 'thumb' => '1629694638.png', 'created_at' => '2021-08-23 04:57:18', 'updated_at' => '2021-08-23 04:57:54', 'equipment_type_id' => '21'), - array('id' => '1046', 'code' => '', 'title' => 'Ratchet Screwdriver', 'brand' => 'Ingco', 'productCode' => 'AKISD0808', 'quantity' => '1', 'specifications' => 'Bits: PH1, PH2, PH3, SL5, SL6, T15, T20', 'description' => '8 Pcs Ratchet Screwdriver Set', 'instructions' => 'Ratchet Screwdrivers or ratcheting screwdrivers, are so-called because they have an integrated ratcheting mechanism as you would find on a ratchet handle for sockets. The ratchet can be switched to fastening or unfastening mode, as well as a neutral mode. (Switch is the Black Ring in the middle-end of the handle)', 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '500.00', 'width' => '3.50', 'length' => '19.50', 'height' => '3.50', 'weight' => '180.00', 'thumb' => '1629694913.jpg', 'created_at' => '2021-08-23 05:01:53', 'updated_at' => '2021-08-23 05:05:07', 'equipment_type_id' => '17'), - array('id' => '1047', 'code' => '', 'title' => '1/2" Socket Set', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'Sizes (in mm): 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 27, 30, 32', 'description' => NULL, 'instructions' => 'Box sockets can be used with handles provided with the set', 'isElectrical' => '1', 'powerRating' => NULL, 'price' => '0.00', 'width' => NULL, 'length' => NULL, 'height' => NULL, 'weight' => NULL, 'thumb' => '1629695416.jpg', 'created_at' => '2021-08-23 05:10:16', 'updated_at' => '2021-08-23 05:10:16', 'equipment_type_id' => '20'), - array('id' => '1048', 'code' => '', 'title' => '1/2" Ratchet Handle', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => '9" Handle, Ratchet Feature', 'description' => 'Can use as a handle for the 1/2" Box Sockets', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '4.50', 'length' => '25.00', 'height' => '3.50', 'weight' => '510.00', 'thumb' => '1629695642.jpg', 'created_at' => '2021-08-23 05:14:02', 'updated_at' => '2021-08-23 05:14:02', 'equipment_type_id' => '20'), - array('id' => '1049', 'code' => '', 'title' => '1/2" Extension Bar', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => '10" Handle', 'description' => 'Can use as an extension handle for the 1/2" Box Sockets', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '2.50', 'length' => '25.00', 'height' => '2.50', 'weight' => '375.00', 'thumb' => '1629695757.jpg', 'created_at' => '2021-08-23 05:15:57', 'updated_at' => '2021-08-23 05:15:57', 'equipment_type_id' => '20'), - array('id' => '1050', 'code' => '', 'title' => '1/2" Universal Joint Adapter', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => '1/2" Universal Joint Adapter', 'description' => 'Can use as an extra converter handle for the 1/2" Box Sockets', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '2.50', 'length' => '7.50', 'height' => '2.50', 'weight' => '130.00', 'thumb' => '1629695915.jpg', 'created_at' => '2021-08-23 05:18:36', 'updated_at' => '2021-08-23 05:18:36', 'equipment_type_id' => '20'), - array('id' => '1051', 'code' => '', 'title' => '16mm 1/2" Spark Plug Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => '16mm', 'description' => 'Specially designed to remove Spark Plugs', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '2.50', 'length' => '6.50', 'height' => '2.50', 'weight' => '85.00', 'thumb' => '1629696124.jpg', 'created_at' => '2021-08-23 05:22:04', 'updated_at' => '2021-08-23 05:22:04', 'equipment_type_id' => '20'), - array('id' => '1052', 'code' => '', 'title' => '22mm 1/2" Spark Plug Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => '22mm', 'description' => 'Specially designed to remove Spark Plugs', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '3.00', 'length' => '6.50', 'height' => '3.00', 'weight' => '135.00', 'thumb' => '1629696225.jpg', 'created_at' => '2021-08-23 05:23:45', 'updated_at' => '2021-08-23 05:23:45', 'equipment_type_id' => '20'), - array('id' => '1053', 'code' => '', 'title' => '12 Pcs Combination Wrench Set', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'Sizes: 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19', 'description' => 'Combination Wrench/Spanner Set', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '36.00', 'length' => '4.00', 'height' => '25.00', 'weight' => NULL, 'thumb' => '1629696350.jpg', 'created_at' => '2021-08-23 05:25:50', 'updated_at' => '2021-08-23 05:26:22', 'equipment_type_id' => '19') + // Tool Board Row 1 + array('id' => '1001', 'code' => '', 'title' => 'Hand Saw', 'brand' => 'Ingco', 'productCode' => 'HHAS28400', 'quantity' => '1', 'specifications' => '400mm/16"', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '780.00', 'width' => '16.00', 'length' => '50.00', 'height' => '3.00', 'weight' => '350.00', 'thumb' => '1655830429.jpg', 'created_at' => '2022-06-21 16:53:49', 'updated_at' => '2022-06-21 16:53:49', 'equipment_type_id' => '22'), + array('id' => '1002', 'code' => '', 'title' => 'Hacksaw', 'brand' => 'Ingco', 'productCode' => 'HHF3028', 'quantity' => '1', 'specifications' => '12" / 300mm HSS Blade', 'description' => 'A saw with a narrow fine-toothed blade set in a frame used especially for cutting metal.', 'instructions' => NULL, 'isElectrical' => '1', 'powerRating' => NULL, 'price' => '600.00', 'width' => '14.00', 'length' => '45.00', 'height' => '2.50', 'weight' => '370.00', 'thumb' => '1629694329.png', 'created_at' => '2021-08-23 04:52:09', 'updated_at' => '2021-08-23 04:52:09', 'equipment_type_id' => '22'), + array('id' => '1003', 'code' => '', 'title' => 'Hand Riveter', 'brand' => 'Jinma', 'productCode' => 'JM-1001', 'quantity' => '1', 'specifications' => 'Nozzles: 2,4 3,2 4,0 4,8', 'description' => '9.5" 240mm Hand Riveter', 'instructions' => 'Plug the rivet, Relax the grip handle, plug in the rivet head, Clamp the grip handle until the rivet pole is broken', 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '620.00', 'width' => '9.00', 'length' => '25.00', 'height' => '5.00', 'weight' => '450.00', 'thumb' => '1629632266.jpg', 'created_at' => '2021-08-22 11:37:47', 'updated_at' => '2021-08-22 11:38:32', 'equipment_type_id' => '11'), + array('id' => '1004', 'code' => '', 'title' => 'Claw Hammer', 'brand' => 'Ingco', 'productCode' => 'HCH880227', 'quantity' => '1', 'specifications' => 'Fiberglass Handle, Drop Forged', 'description' => 'Claw Hammer', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '800.00', 'width' => '14.00', 'length' => '33.00', 'height' => '3.00', 'weight' => '650.00', 'thumb' => '1629694153.jpg', 'created_at' => '2021-08-23 04:49:13', 'updated_at' => '2021-08-23 04:49:13', 'equipment_type_id' => '23'), + array('id' => '1005', 'code' => '', 'title' => 'Rubber Hammer', 'brand' => 'Ingco', 'productCode' => 'RUG3316', 'quantity' => '1', 'specifications' => '16oz/450g', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '860.00', 'width' => '10.00', 'length' => '32.00', 'height' => '7.00', 'weight' => '720.00', 'thumb' => '1655830611.jpg', 'created_at' => '2022-06-21 16:56:51', 'updated_at' => '2022-06-21 16:56:51', 'equipment_type_id' => '23'), + array('id' => '1006', 'code' => '', 'title' => 'Hex Key Set', 'brand' => 'Ingco', 'productCode' => 'HHK11091', 'quantity' => '1', 'specifications' => '9pcs, Sizes: 1.5mm, 2.0mm, 2.5mm, 3.0mm, 4.0mm, 5.0mm, 6.0mm, 8.0mm, 10.0mm,', 'description' => 'Hex / Allen Key Set, Long Arm', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '1100.00', 'width' => '7.50', 'length' => '18.00', 'height' => '3.00', 'weight' => '360.00', 'thumb' => '1629685225.jpg', 'created_at' => '2021-08-23 02:20:25', 'updated_at' => '2022-06-22 07:01:55', 'equipment_type_id' => '11'), + array('id' => '1007', 'code' => '', 'title' => 'Torx Key Set', 'brand' => 'TOTAL', 'productCode' => 'THT106392', 'quantity' => '1', 'specifications' => 'T10, T15, T20, T25, T27, T30, T40, T45, T50', 'description' => '9 Pcs Torx Key Set', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '1100.00', 'width' => '7.50', 'length' => '18.00', 'height' => '3.00', 'weight' => '340.00', 'thumb' => '1629685472.jpg', 'created_at' => '2021-08-23 02:24:32', 'updated_at' => '2022-06-22 07:02:10', 'equipment_type_id' => '11'), + array('id' => '1008', 'code' => '', 'title' => 'Trigeminal Socket Wrench', 'brand' => 'Ingco', 'productCode' => 'HYW081012', 'quantity' => '1', 'specifications' => 'Socket Sizes: 8, 10, 12', 'description' => 'Y Type Socket Wrench', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '500.00', 'width' => '25.00', 'length' => '21.00', 'height' => '2.00', 'weight' => '265.00', 'thumb' => '1629693629.jpg', 'created_at' => '2021-08-23 04:40:29', 'updated_at' => '2022-06-22 06:57:22', 'equipment_type_id' => '27'), + array('id' => '1009', 'code' => '', 'title' => 'Measuring Tape', 'brand' => 'Ingco', 'productCode' => 'HSMT08052', 'quantity' => '2', 'specifications' => 'Length: 5m, Tape width: 19mm', 'description' => 'Measuring tape', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '475.00', 'width' => '9.50', 'length' => '7.50', 'height' => '4.00', 'weight' => '200.00', 'thumb' => '1629632813.png', 'created_at' => '2021-08-22 11:46:53', 'updated_at' => '2021-08-22 11:46:53', 'equipment_type_id' => '15'), + array('id' => '1010', 'code' => '', 'title' => 'Paper Cutter', 'brand' => 'Ingco', 'productCode' => 'HKNS16618', 'quantity' => '3', 'specifications' => '18x100mm', 'description' => 'Snap-off Blade Knife', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '300.00', 'width' => '4.00', 'length' => '18.00', 'height' => '2.50', 'weight' => '85.00', 'thumb' => '1629633529.png', 'created_at' => '2021-08-22 11:58:50', 'updated_at' => '2021-08-22 11:58:50', 'equipment_type_id' => '22'), + array('id' => '1011', 'code' => '', 'title' => 'Carpenter Square', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '2', 'specifications' => NULL, 'description' => 'Used in carpentry, to lay out structures that are square', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '250.00', 'width' => '30.00', 'length' => '13.00', 'height' => '1.50', 'weight' => '100.00', 'thumb' => '1629632925.jpg', 'created_at' => '2021-08-22 11:48:45', 'updated_at' => '2021-08-22 11:48:45', 'equipment_type_id' => '15'), + array('id' => '1012', 'code' => '', 'title' => 'Spirit Level', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '1', 'specifications' => '45cm', 'description' => 'A Spirit Level is a tool used to indicate how parallel (level) or perpendicular (plumb) a surface is relative to the earth', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '775.00', 'width' => '2.00', 'length' => '45.00', 'height' => '5.00', 'weight' => '160.00', 'thumb' => '1629633015.jpg', 'created_at' => '2021-08-22 11:50:16', 'updated_at' => '2021-08-22 11:50:16', 'equipment_type_id' => '15'), + array('id' => '1013', 'code' => '', 'title' => 'Metal Ruler', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '2', 'specifications' => '30cm, Stainless Steel', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '50.00', 'width' => '3.00', 'length' => '31.00', 'height' => '0.20', 'weight' => '50.00', 'thumb' => '1655830721.jpg', 'created_at' => '2022-06-21 16:58:41', 'updated_at' => '2022-06-21 16:58:41', 'equipment_type_id' => '15'), + + // Tool Board Row 2 + array('id' => '1014', 'code' => '', 'title' => 'Diagonal Cutting Plier', 'brand' => 'Ingco', 'productCode' => 'HDCP08168', 'quantity' => '1', 'specifications' => '160mm / 6"', 'description' => 'Diagonal Cutting Plier', 'instructions' => NULL, 'isElectrical' => '1', 'powerRating' => NULL, 'price' => '600.00', 'width' => '6.00', 'length' => '17.00', 'height' => '2.00', 'weight' => '200.00', 'thumb' => '1629684517.jpg', 'created_at' => '2021-08-23 02:08:37', 'updated_at' => '2021-08-23 02:08:37', 'equipment_type_id' => '18'), + array('id' => '1015', 'code' => '', 'title' => 'Combination Plier 8"', 'brand' => 'Ingco', 'productCode' => 'HCP2208', 'quantity' => '1', 'specifications' => '200mm / 8"', 'description' => 'Combination Plier', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '850.00', 'width' => '7.00', 'length' => '20.50', 'height' => '3.50', 'weight' => '325.00', 'thumb' => '1629684152.jpg', 'created_at' => '2021-08-23 02:02:33', 'updated_at' => '2022-06-21 17:02:59', 'equipment_type_id' => '18'), + array('id' => '1016', 'code' => '', 'title' => 'Long Nose Plier', 'brand' => 'Ingco', 'productCode' => 'HLNP08168', 'quantity' => '4', 'specifications' => '160mm / 6"', 'description' => 'Long Nose Plier', 'instructions' => NULL, 'isElectrical' => '1', 'powerRating' => NULL, 'price' => '600.00', 'width' => '6.00', 'length' => '17.00', 'height' => '2.00', 'weight' => '120.00', 'thumb' => '1629684307.jpg', 'created_at' => '2021-08-23 02:05:08', 'updated_at' => '2021-08-23 02:05:08', 'equipment_type_id' => '18'), + array('id' => '1017', 'code' => '', 'title' => 'Straight Aviation Snip', 'brand' => 'Ingco', 'productCode' => 'HTSN0110S', 'quantity' => '1', 'specifications' => 'Length 250mm', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '930.00', 'width' => '7.00', 'length' => '26.00', 'height' => '3.50', 'weight' => '400.00', 'thumb' => '1655831099.jpg', 'created_at' => '2022-06-21 17:04:59', 'updated_at' => '2022-06-21 17:04:59', 'equipment_type_id' => '22'), + array('id' => '1018', 'code' => '', 'title' => 'Wood Chisel', 'brand' => 'Ingco', 'productCode' => 'HWC0819', 'quantity' => '1', 'specifications' => '19mm (3/4")', 'description' => 'Wood Chisel', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '580.00', 'width' => '4.50', 'length' => '27.00', 'height' => '4.50', 'weight' => '200.00', 'thumb' => '1629693911.jpg', 'created_at' => '2021-08-23 04:45:11', 'updated_at' => '2021-08-23 04:45:11', 'equipment_type_id' => '22'), + array('id' => '1019', 'code' => '', 'title' => 'Flathead Screwdriver 8x150', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Flathead Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '300.00', 'width' => '4.00', 'length' => '28.00', 'height' => '4.00', 'weight' => '150.00', 'thumb' => '1629197752.jpg', 'created_at' => '2021-08-17 10:55:53', 'updated_at' => '2021-08-22 12:19:07', 'equipment_type_id' => '17'), + array('id' => '1020', 'code' => '', 'title' => 'Phillips head Screwdriver PH3x150', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Phillips head Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '300.00', 'width' => '4.00', 'length' => '28.00', 'height' => '4.00', 'weight' => '150.00', 'thumb' => '1629198303.jpg', 'created_at' => '2021-08-17 11:05:03', 'updated_at' => '2021-08-22 12:20:12', 'equipment_type_id' => '17'), + array('id' => '1021', 'code' => '', 'title' => 'Flat Steel File', 'brand' => 'Juneng', 'productCode' => 'JN100405', 'quantity' => '1', 'specifications' => '8"', 'description' => 'Flat Steel File', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '690.00', 'width' => '4.00', 'length' => '31.00', 'height' => '4.00', 'weight' => '200.00', 'thumb' => '1629630306.jpg', 'created_at' => '2021-08-22 11:05:06', 'updated_at' => '2021-08-22 11:05:06', 'equipment_type_id' => '25'), + array('id' => '1022', 'code' => '', 'title' => 'Half Round Steel File', 'brand' => 'Juneng', 'productCode' => 'JN100404', 'quantity' => '1', 'specifications' => 'Half Round Steel File', 'description' => 'Half Round Steel File', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '725.00', 'width' => '4.00', 'length' => '31.00', 'height' => '4.00', 'weight' => '200.00', 'thumb' => '1629630519.jpg', 'created_at' => '2021-08-22 11:08:39', 'updated_at' => '2021-08-22 11:08:50', 'equipment_type_id' => '25'), + array('id' => '1023', 'code' => '', 'title' => '1/2" Ratchet Handle', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => '9" Handle, Ratchet Feature', 'description' => 'Can use as a handle for the 1/2" Box Sockets', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '4.50', 'length' => '25.00', 'height' => '3.50', 'weight' => '510.00', 'thumb' => '1629695642.jpg', 'created_at' => '2021-08-23 05:14:02', 'updated_at' => '2021-08-23 05:14:02', 'equipment_type_id' => '20'), + array('id' => '1024', 'code' => '', 'title' => 'Adjustable Wrench', 'brand' => 'Ingco', 'productCode' => 'HADW131088', 'quantity' => '1', 'specifications' => '200mm handle, Max 30mm Jaw', 'description' => 'Adjustable Wrench', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '950.00', 'width' => '7.00', 'length' => '21.50', 'height' => '2.50', 'weight' => '300.00', 'thumb' => '1629693477.png', 'created_at' => '2021-08-23 04:37:58', 'updated_at' => '2022-06-22 06:57:04', 'equipment_type_id' => '27'), + + // Wrench Set + array('id' => '1025', 'code' => '', 'title' => 'Size 19 Wrench', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'Size 19', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '3.00', 'length' => '23.00', 'height' => '1.00', 'weight' => '160.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:06:38', 'updated_at' => '2022-06-21 17:09:11', 'equipment_type_id' => '19'), + array('id' => '1026', 'code' => '', 'title' => 'Size 18 Wrench', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'Size 18', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '3.00', 'length' => '22.00', 'height' => '1.00', 'weight' => '145.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:06:38', 'updated_at' => '2022-06-21 17:09:11', 'equipment_type_id' => '19'), + array('id' => '1027', 'code' => '', 'title' => 'Size 17 Wrench', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'Size 17', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '3.00', 'length' => '21.00', 'height' => '1.00', 'weight' => '110.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:06:38', 'updated_at' => '2022-06-21 17:09:11', 'equipment_type_id' => '19'), + array('id' => '1028', 'code' => '', 'title' => 'Size 16 Wrench', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'Size 16', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '2.50', 'length' => '20.00', 'height' => '1.00', 'weight' => '110.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:06:38', 'updated_at' => '2022-06-21 17:09:11', 'equipment_type_id' => '19'), + array('id' => '1029', 'code' => '', 'title' => 'Size 15 Wrench', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'Size 15', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '2.50', 'length' => '20.00', 'height' => '1.00', 'weight' => '110.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:06:38', 'updated_at' => '2022-06-21 17:09:11', 'equipment_type_id' => '19'), + array('id' => '1030', 'code' => '', 'title' => 'Size 14 Wrench', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'Size 14', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '2.50', 'length' => '19.00', 'height' => '1.00', 'weight' => '95.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:06:38', 'updated_at' => '2022-06-21 17:09:11', 'equipment_type_id' => '19'), + array('id' => '1031', 'code' => '', 'title' => 'Size 13 Wrench', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'Size 13', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '2.50', 'length' => '17.00', 'height' => '1.00', 'weight' => '65.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:06:38', 'updated_at' => '2022-06-21 17:09:11', 'equipment_type_id' => '19'), + array('id' => '1032', 'code' => '', 'title' => 'Size 12 Wrench', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'Size 12', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '2.00', 'length' => '16.00', 'height' => '1.00', 'weight' => '60.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:06:38', 'updated_at' => '2022-06-21 17:09:11', 'equipment_type_id' => '19'), + array('id' => '1033', 'code' => '', 'title' => 'Size 11 Wrench', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'Size 11', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '2.00', 'length' => '16.00', 'height' => '1.00', 'weight' => '65.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:06:38', 'updated_at' => '2022-06-21 17:09:11', 'equipment_type_id' => '19'), + array('id' => '1034', 'code' => '', 'title' => 'Size 10 Wrench', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'Size 10', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '2.00', 'length' => '14.00', 'height' => '1.00', 'weight' => '50.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:06:38', 'updated_at' => '2022-06-21 17:09:11', 'equipment_type_id' => '19'), + array('id' => '1035', 'code' => '', 'title' => 'Size 9 Wrench', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'Size 9', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '1.50', 'length' => '13.00', 'height' => '1.00', 'weight' => '35.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:06:38', 'updated_at' => '2022-06-21 17:09:11', 'equipment_type_id' => '19'), + array('id' => '1036', 'code' => '', 'title' => 'Size 8 Wrench', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'Size 8', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '1.50', 'length' => '12.00', 'height' => '1.00', 'weight' => '25.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:06:38', 'updated_at' => '2022-06-21 17:09:11', 'equipment_type_id' => '19'), + + array('id' => '1037', 'code' => '', 'title' => '1/2" Extension Bar', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => '10" Handle', 'description' => 'Can use as an extension handle for the 1/2" Box Sockets', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '2.50', 'length' => '25.00', 'height' => '2.50', 'weight' => '375.00', 'thumb' => '1629695757.jpg', 'created_at' => '2021-08-23 05:15:57', 'updated_at' => '2021-08-23 05:15:57', 'equipment_type_id' => '20'), + + // Half Socket Set + array('id' => '1038', 'code' => '', 'title' => 'Size 8 Half Inch Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => NULL, 'length' => NULL, 'height' => NULL, 'weight' => '52.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:08:42', 'updated_at' => '2022-06-21 17:08:58', 'equipment_type_id' => '20'), + array('id' => '1039', 'code' => '', 'title' => 'Size 9 Half Inch Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => NULL, 'length' => NULL, 'height' => NULL, 'weight' => '50.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:08:42', 'updated_at' => '2022-06-21 17:08:58', 'equipment_type_id' => '20'), + array('id' => '1040', 'code' => '', 'title' => 'Size 10 Half Inch Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => NULL, 'length' => NULL, 'height' => NULL, 'weight' => '52.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:08:42', 'updated_at' => '2022-06-21 17:08:58', 'equipment_type_id' => '20'), + array('id' => '1041', 'code' => '', 'title' => 'Size 11 Half Inch Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => NULL, 'length' => NULL, 'height' => NULL, 'weight' => '50.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:08:42', 'updated_at' => '2022-06-21 17:08:58', 'equipment_type_id' => '20'), + array('id' => '1042', 'code' => '', 'title' => 'Size 12 Half Inch Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => NULL, 'length' => NULL, 'height' => NULL, 'weight' => '50.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:08:42', 'updated_at' => '2022-06-21 17:08:58', 'equipment_type_id' => '20'), + array('id' => '1043', 'code' => '', 'title' => 'Size 13 Half Inch Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => NULL, 'length' => NULL, 'height' => NULL, 'weight' => '55.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:08:42', 'updated_at' => '2022-06-21 17:08:58', 'equipment_type_id' => '20'), + array('id' => '1044', 'code' => '', 'title' => 'Size 14 Half Inch Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => NULL, 'length' => NULL, 'height' => NULL, 'weight' => '55.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:08:42', 'updated_at' => '2022-06-21 17:08:58', 'equipment_type_id' => '20'), + array('id' => '1045', 'code' => '', 'title' => 'Size 15 Half Inch Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => NULL, 'length' => NULL, 'height' => NULL, 'weight' => '50.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:08:42', 'updated_at' => '2022-06-21 17:08:58', 'equipment_type_id' => '20'), + array('id' => '1046', 'code' => '', 'title' => 'Size 16 Half Inch Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => NULL, 'length' => NULL, 'height' => NULL, 'weight' => '50.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:08:42', 'updated_at' => '2022-06-21 17:08:58', 'equipment_type_id' => '20'), + array('id' => '1047', 'code' => '', 'title' => 'Size 17 Half Inch Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => NULL, 'length' => NULL, 'height' => NULL, 'weight' => '60.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:08:42', 'updated_at' => '2022-06-21 17:08:58', 'equipment_type_id' => '20'), + array('id' => '1048', 'code' => '', 'title' => 'Size 18 Half Inch Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => NULL, 'length' => NULL, 'height' => NULL, 'weight' => '70.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:08:42', 'updated_at' => '2022-06-21 17:08:58', 'equipment_type_id' => '20'), + array('id' => '1049', 'code' => '', 'title' => 'Size 19 Half Inch Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => NULL, 'length' => NULL, 'height' => NULL, 'weight' => '60.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:08:42', 'updated_at' => '2022-06-21 17:08:58', 'equipment_type_id' => '20'), + array('id' => '1050', 'code' => '', 'title' => 'Size 20 Half Inch Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => NULL, 'length' => NULL, 'height' => NULL, 'weight' => '75.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:08:42', 'updated_at' => '2022-06-21 17:08:58', 'equipment_type_id' => '20'), + array('id' => '1051', 'code' => '', 'title' => 'Size 21 Half Inch Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => NULL, 'length' => NULL, 'height' => NULL, 'weight' => '70.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:08:42', 'updated_at' => '2022-06-21 17:08:58', 'equipment_type_id' => '20'), + array('id' => '1052', 'code' => '', 'title' => 'Size 22 Half Inch Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => NULL, 'length' => NULL, 'height' => NULL, 'weight' => '95.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:08:42', 'updated_at' => '2022-06-21 17:08:58', 'equipment_type_id' => '20'), + array('id' => '1053', 'code' => '', 'title' => 'Size 24 Half Inch Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => NULL, 'length' => NULL, 'height' => NULL, 'weight' => '105.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:08:42', 'updated_at' => '2022-06-21 17:08:58', 'equipment_type_id' => '20'), + array('id' => '1054', 'code' => '', 'title' => 'Size 27 Half Inch Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => NULL, 'length' => NULL, 'height' => NULL, 'weight' => '135.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:08:42', 'updated_at' => '2022-06-21 17:08:58', 'equipment_type_id' => '20'), + array('id' => '1055', 'code' => '', 'title' => 'Size 30 Half Inch Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => NULL, 'length' => NULL, 'height' => NULL, 'weight' => '180.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:08:42', 'updated_at' => '2022-06-21 17:08:58', 'equipment_type_id' => '20'), + array('id' => '1056', 'code' => '', 'title' => 'Size 32 Half Inch Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => NULL, 'length' => NULL, 'height' => NULL, 'weight' => '195.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:08:42', 'updated_at' => '2022-06-21 17:08:58', 'equipment_type_id' => '20'), + + array('id' => '1057', 'code' => '', 'title' => '1/2" Universal Joint Adapter', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => '1/2" Universal Joint Adapter', 'description' => 'Can use as an extra converter handle for the 1/2" Box Sockets', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '2.50', 'length' => '7.50', 'height' => '2.50', 'weight' => '130.00', 'thumb' => '1629695915.jpg', 'created_at' => '2021-08-23 05:18:36', 'updated_at' => '2021-08-23 05:18:36', 'equipment_type_id' => '20'), + array('id' => '1058', 'code' => '', 'title' => '16mm 1/2" Spark Plug Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => '16mm', 'description' => 'Specially designed to remove Spark Plugs', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '2.50', 'length' => '6.50', 'height' => '2.50', 'weight' => '85.00', 'thumb' => '1629696124.jpg', 'created_at' => '2021-08-23 05:22:04', 'updated_at' => '2021-08-23 05:22:04', 'equipment_type_id' => '20'), + array('id' => '1059', 'code' => '', 'title' => '22mm 1/2" Spark Plug Socket', 'brand' => 'SATAGOOD', 'productCode' => NULL, 'quantity' => '1', 'specifications' => '22mm', 'description' => 'Specially designed to remove Spark Plugs', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '3.00', 'length' => '6.50', 'height' => '3.00', 'weight' => '135.00', 'thumb' => '1629696225.jpg', 'created_at' => '2021-08-23 05:23:45', 'updated_at' => '2021-08-23 05:23:45', 'equipment_type_id' => '20'), + + // Assembly Station + array('id' => '1060', 'code' => '', 'title' => 'Flathead Screwdriver 6x100', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Flathead Screwdriver 6x100', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '250.00', 'width' => '4.00', 'length' => '22.00', 'height' => '4.00', 'weight' => '90.00', 'thumb' => '1629198096.jpg', 'created_at' => '2021-08-17 11:01:36', 'updated_at' => '2021-08-22 12:19:37', 'equipment_type_id' => '17'), + array('id' => '1061', 'code' => '', 'title' => 'Flathead Screwdriver 5x75', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Flathead Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '200.00', 'width' => '3.00', 'length' => '18.00', 'height' => '3.00', 'weight' => '60.00', 'thumb' => '1629198157.jpg', 'created_at' => '2021-08-17 11:02:37', 'updated_at' => '2021-08-22 12:19:53', 'equipment_type_id' => '17'), + array('id' => '1062', 'code' => '', 'title' => 'Screw Bit Holder', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Screw Bit Holder', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '200.00', 'width' => '4.00', 'length' => '18.00', 'height' => '4.00', 'weight' => '120.00', 'thumb' => '1629198659.jpg', 'created_at' => '2021-08-17 11:11:00', 'updated_at' => '2021-08-22 12:21:03', 'equipment_type_id' => '17'), + array('id' => '1063', 'code' => '', 'title' => 'Phillips head Screwdriver PH1x75', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Phillips head Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '200.00', 'width' => '3.00', 'length' => '18.00', 'height' => '3.00', 'weight' => '60.00', 'thumb' => '1629198418.jpg', 'created_at' => '2021-08-17 11:06:58', 'updated_at' => '2021-08-22 12:20:22', 'equipment_type_id' => '17'), + array('id' => '1064', 'code' => '', 'title' => 'Phillips head Screwdriver PH2x100', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Phillips head Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '250.00', 'width' => '4.00', 'length' => '22.00', 'height' => '4.00', 'weight' => '90.00', 'thumb' => '1629198371.jpg', 'created_at' => '2021-08-17 11:06:11', 'updated_at' => '2021-08-22 12:20:17', 'equipment_type_id' => '17'), + array('id' => '1065', 'code' => '', 'title' => 'Flathead Screwdriver 6x38', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Flathead Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '100.00', 'width' => '4.00', 'length' => '11.00', 'height' => '4.00', 'weight' => '50.00', 'thumb' => '1629198526.jpg', 'created_at' => '2021-08-17 11:08:46', 'updated_at' => '2021-08-22 12:20:42', 'equipment_type_id' => '17'), + array('id' => '1066', 'code' => '', 'title' => 'Phillips head Screwdriver PH2x38', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Phillips head Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '100.00', 'width' => '4.00', 'length' => '11.00', 'height' => '4.00', 'weight' => '50.00', 'thumb' => '1629198571.jpg', 'created_at' => '2021-08-17 11:09:31', 'updated_at' => '2021-08-22 12:20:46', 'equipment_type_id' => '17'), + array('id' => '1067', 'code' => '', 'title' => 'Flathead Precision Screwdriver 3x50', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Flathead Precision Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '150.00', 'width' => '2.00', 'length' => '14.00', 'height' => '2.00', 'weight' => '15.00', 'thumb' => '1629198802.jpg', 'created_at' => '2021-08-17 11:13:22', 'updated_at' => '2021-08-22 12:21:27', 'equipment_type_id' => '17'), + array('id' => '1068', 'code' => '', 'title' => 'Flathead Precision Screwdriver 2.5x50', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Flathead Precision Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '150.00', 'width' => '2.00', 'length' => '14.00', 'height' => '2.00', 'weight' => '15.00', 'thumb' => '1629198869.jpg', 'created_at' => '2021-08-17 11:14:30', 'updated_at' => '2021-08-22 12:21:32', 'equipment_type_id' => '17'), + array('id' => '1069', 'code' => '', 'title' => 'Flathead Precision Screwdriver 2x50', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Flathead Precision Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '150.00', 'width' => '2.00', 'length' => '14.00', 'height' => '2.00', 'weight' => '15.00', 'thumb' => '1629198912.jpg', 'created_at' => '2021-08-17 11:15:13', 'updated_at' => '2021-08-22 12:21:36', 'equipment_type_id' => '17'), + array('id' => '1070', 'code' => '', 'title' => 'Phillips head Screwdriver PH0x50', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Phillips head Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '150.00', 'width' => '2.00', 'length' => '14.00', 'height' => '2.00', 'weight' => '15.00', 'thumb' => '1629199000.jpg', 'created_at' => '2021-08-17 11:16:40', 'updated_at' => '2021-08-22 12:21:41', 'equipment_type_id' => '17'), + array('id' => '1071', 'code' => '', 'title' => 'Phillips head Screwdriver PH00x50', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Phillips head Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '150.00', 'width' => '2.00', 'length' => '14.00', 'height' => '2.00', 'weight' => '15.00', 'thumb' => '1629199040.jpg', 'created_at' => '2021-08-17 11:17:20', 'updated_at' => '2021-08-22 12:21:45', 'equipment_type_id' => '17'), + array('id' => '1072', 'code' => '', 'title' => 'Torx Precision Screwdriver T6x50', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Torx Precision Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '150.00', 'width' => '2.00', 'length' => '14.00', 'height' => '2.00', 'weight' => '15.00', 'thumb' => '1629199113.jpg', 'created_at' => '2021-08-17 11:18:33', 'updated_at' => '2021-08-22 12:21:53', 'equipment_type_id' => '17'), + array('id' => '1073', 'code' => '', 'title' => 'Torx Precision Screwdriver T8x50', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Torx Precision Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '150.00', 'width' => '2.00', 'length' => '14.00', 'height' => '2.00', 'weight' => '15.00', 'thumb' => '1629199145.jpg', 'created_at' => '2021-08-17 11:19:05', 'updated_at' => '2021-08-22 12:21:56', 'equipment_type_id' => '17'), + array('id' => '1074', 'code' => '', 'title' => 'Torx Precision Screwdriver T10x50', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'Torx Precision Screwdriver', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '150.00', 'width' => '2.00', 'length' => '14.00', 'height' => '2.00', 'weight' => '15.00', 'thumb' => '1629199178.jpg', 'created_at' => '2021-08-17 11:19:38', 'updated_at' => '2021-08-22 12:22:20', 'equipment_type_id' => '17'), + array('id' => '1075', 'code' => '', 'title' => '1/4 Bits Set', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => '1/4 Bits Set Flathead 4,5,6 Phillips head PH0, PH1, PH2, PZ1, PZ2 Torx T20, T25, T30 Hex 2, 3, 4, 5, 67', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '300.00', 'width' => '7.00', 'length' => '1.50', 'height' => '7.00', 'weight' => '0.00', 'thumb' => '1629199501.jpg', 'created_at' => '2021-08-17 11:25:01', 'updated_at' => '2021-08-22 12:22:51', 'equipment_type_id' => '17'), + array('id' => '1076', 'code' => '', 'title' => '1/4 Socket Set', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => '1/4 Sockets Sockets: 6, 7, 8, 9, 10', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '300.00', 'width' => '7.00', 'length' => '1.50', 'height' => '5.00', 'weight' => '0.00', 'thumb' => '1629199664.jpg', 'created_at' => '2021-08-17 11:27:45', 'updated_at' => '2021-08-22 12:22:56', 'equipment_type_id' => '24'), + array('id' => '1077', 'code' => '', 'title' => 'Megnetizer and Demagnetizer', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'This can be used to magnetize or de-magnetize the screwdriver heads', 'instructions' => 'https://www.youtube.com/watch?v=Z0gAdLvlrHA', 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '250.00', 'width' => '2.00', 'length' => '2.00', 'height' => '5.00', 'weight' => '0.00', 'thumb' => '1629199801.jpg', 'created_at' => '2021-08-17 11:30:01', 'updated_at' => '2021-08-22 12:23:11', 'equipment_type_id' => '17'), + array('id' => '1078', 'code' => '', 'title' => 'Flexible Shaft Screwdriver', 'brand' => 'Ingco', 'productCode' => 'AKSDFL1208', 'quantity' => '1', 'specifications' => 'Comes with bits of SL5,SL6,SL7,PH1,PH2,PH3,T10,T15,T20,T25', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '550.00', 'width' => '4.00', 'length' => '30.00', 'height' => '4.00', 'weight' => '155.00', 'thumb' => '1655831499.jpg', 'created_at' => '2022-06-21 17:11:39', 'updated_at' => '2022-06-21 17:14:46', 'equipment_type_id' => '17'), + array('id' => '1079', 'code' => '', 'title' => 'Ratchet Screwdriver', 'brand' => 'Ingco', 'productCode' => 'AKISD0808', 'quantity' => '1', 'specifications' => 'Bits: PH1, PH2, PH3, SL5, SL6, T15, T20', 'description' => '8 Pcs Ratchet Screwdriver Set', 'instructions' => 'Ratchet Screwdrivers or ratcheting screwdrivers, are so-called because they have an integrated ratcheting mechanism as you would find on a ratchet handle for sockets. The ratchet can be switched to fastening or unfastening mode, as well as a neutral mode. (Switch is the Black Ring in the middle-end of the handle)', 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '500.00', 'width' => '3.50', 'length' => '19.50', 'height' => '3.50', 'weight' => '180.00', 'thumb' => '1629694913.jpg', 'created_at' => '2021-08-23 05:01:53', 'updated_at' => '2021-08-23 05:05:07', 'equipment_type_id' => '17'), + array('id' => '1080', 'code' => '', 'title' => '6 pcs Precision Screw Driver Set', 'brand' => 'Ingco', 'productCode' => 'HKSD0618', 'quantity' => '1', 'specifications' => 'Comes in an enclosure box, SL2.0, SL2.5, SL 3.0, PH000, PH00, PH0', 'description' => 'Precision Screwdriver Set', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '700.00', 'width' => '9.00', 'length' => '15.00', 'height' => '2.50', 'weight' => '145.00', 'thumb' => '1629684973.jpg', 'created_at' => '2021-08-23 02:16:14', 'updated_at' => '2021-08-23 02:16:14', 'equipment_type_id' => '17'), + + array('id' => '1081', 'code' => '', 'title' => 'Size 6-7 Double Open Wrench', 'brand' => 'Ingco', 'productCode' => 'HKSPA2088', 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '286.00', 'width' => '2.00', 'length' => '110.00', 'height' => '1.00', 'weight' => '30.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:37:42', 'updated_at' => '2022-06-21 17:39:46', 'equipment_type_id' => '26'), + array('id' => '1082', 'code' => '', 'title' => 'Size 8-9 Double Open Wrench', 'brand' => 'Ingco', 'productCode' => 'HKSPA2088', 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '286.00', 'width' => '2.50', 'length' => '130.00', 'height' => '1.00', 'weight' => '40.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:37:42', 'updated_at' => '2022-06-21 17:39:46', 'equipment_type_id' => '26'), + array('id' => '1083', 'code' => '', 'title' => 'Size 10-11 Double Open Wrench', 'brand' => 'Ingco', 'productCode' => 'HKSPA2088', 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '286.00', 'width' => '3.00', 'length' => '140.00', 'height' => '1.00', 'weight' => '60.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:37:42', 'updated_at' => '2022-06-21 17:39:46', 'equipment_type_id' => '26'), + array('id' => '1084', 'code' => '', 'title' => 'Size 12-13 Double Open Wrench', 'brand' => 'Ingco', 'productCode' => 'HKSPA2088', 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '286.00', 'width' => '3.00', 'length' => '155.00', 'height' => '1.00', 'weight' => '80.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:37:42', 'updated_at' => '2022-06-21 17:39:46', 'equipment_type_id' => '26'), + array('id' => '1085', 'code' => '', 'title' => 'Size 14-15 Double Open Wrench', 'brand' => 'Ingco', 'productCode' => 'HKSPA2088', 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '286.00', 'width' => '3.50', 'length' => '170.00', 'height' => '1.00', 'weight' => '110.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:37:42', 'updated_at' => '2022-06-21 17:39:46', 'equipment_type_id' => '26'), + array('id' => '1086', 'code' => '', 'title' => 'Size 16-17 Double Open Wrench', 'brand' => 'Ingco', 'productCode' => 'HKSPA2088', 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '286.00', 'width' => '4.00', 'length' => '180.00', 'height' => '1.00', 'weight' => '120.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:37:42', 'updated_at' => '2022-06-21 17:39:46', 'equipment_type_id' => '26'), + array('id' => '1087', 'code' => '', 'title' => 'Size 18-19 Double Open Wrench', 'brand' => 'Ingco', 'productCode' => 'HKSPA2088', 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '286.00', 'width' => '4.00', 'length' => '190.00', 'height' => '1.00', 'weight' => '150.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:37:42', 'updated_at' => '2022-06-21 17:39:46', 'equipment_type_id' => '26'), + array('id' => '1088', 'code' => '', 'title' => 'Size 20-22 Double Open Wrench', 'brand' => 'Ingco', 'productCode' => 'HKSPA2088', 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '286.00', 'width' => '5.00', 'length' => '210.00', 'height' => '1.00', 'weight' => '200.00', 'thumb' => NULL, 'created_at' => '2022-06-21 17:37:42', 'updated_at' => '2022-06-21 17:39:46', 'equipment_type_id' => '26'), + + array('id' => '1089', 'code' => '', 'title' => 'Wire Cutter (Red)', 'brand' => 'Juneng', 'productCode' => NULL, 'quantity' => '2', 'specifications' => NULL, 'description' => 'Wire Cutter, this can be used to cut the small circuit wires', 'instructions' => NULL, 'isElectrical' => '1', 'powerRating' => NULL, 'price' => '325.00', 'width' => '6.50', 'length' => '12.00', 'height' => '1.50', 'weight' => '65.00', 'thumb' => '1629630731.jpg', 'created_at' => '2021-08-22 11:12:11', 'updated_at' => '2021-08-22 11:12:11', 'equipment_type_id' => '22'), + array('id' => '1090', 'code' => '', 'title' => 'Combination Plier 7"', 'brand' => 'Ingco', 'productCode' => 'HCP08188', 'quantity' => '1', 'specifications' => '180mm / 7"', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '705.00', 'width' => '7.00', 'length' => '21.00', 'height' => '3.00', 'weight' => '330.00', 'thumb' => '1655830957.jpg', 'created_at' => '2022-06-21 17:02:37', 'updated_at' => '2022-06-21 17:02:37', 'equipment_type_id' => '18'), + array('id' => '1091', 'code' => '', 'title' => 'Multi Functional Scissor', 'brand' => 'Ingco', 'productCode' => 'HSCRS2301', 'quantity' => '2', 'specifications' => '9"', 'description' => 'Features: 1. Scissors 2. Wire Cutter 3. Twine Cutter 4. Power Notch For Rope 5. Pointed Awl Tip 6.Bottle Opener', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '1050.00', 'width' => '8.00', 'length' => '24.00', 'height' => '2.00', 'weight' => '120.00', 'thumb' => '1655832470.jpg', 'created_at' => '2022-06-21 17:27:50', 'updated_at' => '2022-06-21 17:27:50', 'equipment_type_id' => '22'), + array('id' => '1092', 'code' => '', 'title' => 'Digital Caliper', 'brand' => 'Ingco', 'productCode' => 'HDCD01150', 'quantity' => '1', 'specifications' => 'Comes with a plastic box and one extra battery, Range: 0-150mm, Reading: 0.01mm, Metric and Inch', 'description' => 'A caliper is a device used to measure the dimensions of an object', 'instructions' => 'Please read the instruction manual in the box for details', 'isElectrical' => '1', 'powerRating' => NULL, 'price' => '4180.00', 'width' => '6.00', 'length' => '25.00', 'height' => '2.50', 'weight' => '300.00', 'thumb' => '1629633245.png', 'created_at' => '2021-08-22 11:54:05', 'updated_at' => '2021-08-22 11:56:00', 'equipment_type_id' => '15'), + array('id' => '1093', 'code' => '', 'title' => 'Combo Square Ruler', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '1', 'specifications' => '30cm, 45/90 degrees, Sprit Level', 'description' => NULL, 'instructions' => 'https://www.youtube.com/watch?v=gG5FwB-OCp8', 'isElectrical' => '1', 'powerRating' => NULL, 'price' => '1150.00', 'width' => '12.00', 'length' => '30.00', 'height' => '1.00', 'weight' => '135.00', 'thumb' => '1655832952.jpg', 'created_at' => '2022-06-21 17:35:52', 'updated_at' => '2022-06-21 17:35:52', 'equipment_type_id' => '15'), + + // Testing Station + array('id' => '1100', 'code' => '', 'title' => 'Flat Head Screwdriver', 'brand' => 'Ingco', 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '160.00', 'width' => '4.00', 'length' => '26.50', 'height' => '4.00', 'weight' => '105.00', 'thumb' => '1655831672.jpg', 'created_at' => '2022-06-21 17:14:32', 'updated_at' => '2022-06-21 17:14:32', 'equipment_type_id' => '17'), + array('id' => '1101', 'code' => '', 'title' => 'Slotted Screwdriver Voltage Tester', 'brand' => 'Ingco', 'productCode' => 'HSDT1408', 'quantity' => '1', 'specifications' => 'Test Voltage – AC 100-500V +Slotted Size – 3x140mm.', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '160.00', 'width' => '2.50', 'length' => '19.00', 'height' => '2.50', 'weight' => '33.00', 'thumb' => '1655831779.jpg', 'created_at' => '2022-06-21 17:16:19', 'updated_at' => '2022-06-22 07:10:50', 'equipment_type_id' => '15'), + array('id' => '1102', 'code' => '', 'title' => 'Digital Logic Probe', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '1', 'powerRating' => NULL, 'price' => '0.00', 'width' => NULL, 'length' => NULL, 'height' => NULL, 'weight' => NULL, 'thumb' => '1656336409.jpg', 'created_at' => '2022-06-27 13:26:50', 'updated_at' => '2022-06-27 13:26:50', 'equipment_type_id' => '15'), + array('id' => '1103', 'code' => '', 'title' => 'Digital Multimeter', 'brand' => 'KYORITSU', 'productCode' => '1021R', 'quantity' => '1', 'specifications' => 'True RMS, Large display with 6000 counts and Backlight,', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '1', 'powerRating' => NULL, 'price' => '0.00', 'width' => '7.50', 'length' => '15.50', 'height' => '3.50', 'weight' => '250.00', 'thumb' => '1658320701.jpg', 'created_at' => '2022-06-27 13:27:08', 'updated_at' => '2022-07-20 12:38:21', 'equipment_type_id' => '15'), + + // Soldering Station + array('id' => '1110', 'code' => '', 'title' => 'Wire Stripper with Crimping', 'brand' => 'Ingco', 'productCode' => 'HWSP101', 'quantity' => '1', 'specifications' => '10" / 250mm', 'description' => 'Can be used to strip the wires and do crimping and cutting the wires', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '1100.00', 'width' => '7.00', 'length' => '26.00', 'height' => '2.50', 'weight' => '325.00', 'thumb' => '1629683896.jpg', 'created_at' => '2021-08-23 01:58:17', 'updated_at' => '2021-08-23 01:58:17', 'equipment_type_id' => '22'), + array('id' => '1111', 'code' => '', 'title' => 'Wire Stripper', 'brand' => 'Ingco', 'productCode' => 'HWSP15608', 'quantity' => '1', 'specifications' => '0.5-6mm range', 'description' => 'Wire Stripper, can be used to remove the rubber part from the copper wires.', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '1200.00', 'width' => '9.00', 'length' => '18.50', 'height' => '2.50', 'weight' => '225.00', 'thumb' => '1629683617.jpg', 'created_at' => '2021-08-23 01:53:37', 'updated_at' => '2021-08-23 01:53:37', 'equipment_type_id' => '22'), + array('id' => '1112', 'code' => '', 'title' => 'Wire Cutter', 'brand' => 'Plato', 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'Max 1mm (0.04") diameter copper wire', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '250.00', 'width' => '8.00', 'length' => '13.00', 'height' => '2.00', 'weight' => '60.00', 'thumb' => '1655831953.jpg', 'created_at' => '2022-06-21 17:19:13', 'updated_at' => '2022-06-21 17:20:23', 'equipment_type_id' => '22'), + array('id' => '1113', 'code' => '', 'title' => 'ESD-10 Tweezer', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'Electrostatic Discharge', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '170.00', 'width' => '1.50', 'length' => '13.00', 'height' => '1.00', 'weight' => '15.00', 'thumb' => '1656166862.jpg', 'created_at' => '2022-06-21 17:40:56', 'updated_at' => '2022-06-21 17:43:20', 'equipment_type_id' => '14'), + array('id' => '1114', 'code' => '', 'title' => 'ESD-13 Tweezer', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '2', 'specifications' => 'Electrostatic Discharge', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '1', 'powerRating' => NULL, 'price' => '170.00', 'width' => '1.50', 'length' => '13.00', 'height' => '1.00', 'weight' => '15.00', 'thumb' => '1655833386.jpg', 'created_at' => '2022-06-21 17:43:06', 'updated_at' => '2022-06-21 17:43:06', 'equipment_type_id' => '14'), + array('id' => '1115', 'code' => '', 'title' => 'ESD-15 Tweezer', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '2', 'specifications' => 'Electrostatic Discharge', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '1', 'powerRating' => NULL, 'price' => '170.00', 'width' => '1.50', 'length' => '13.00', 'height' => '1.00', 'weight' => '15.00', 'thumb' => '1655833449.jpg', 'created_at' => '2022-06-21 17:44:09', 'updated_at' => '2022-06-21 17:44:09', 'equipment_type_id' => '14'), + array('id' => '1116', 'code' => '', 'title' => 'Desoldering Tool', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'Tip Inner Hole Dia. : 3mm/ 0.12"', 'description' => NULL, 'instructions' => 'When the solder melts, push the release button and a retracting plunger creates a strong vacuum at the tip, removing the melted solder.', 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '180.00', 'width' => '2.00', 'length' => '18.50', 'height' => '2.00', 'weight' => '25.00', 'thumb' => '1655832631.jpg', 'created_at' => '2022-06-21 17:30:32', 'updated_at' => '2022-06-21 17:30:32', 'equipment_type_id' => '14'), + array('id' => '1117', 'code' => '', 'title' => 'Soldering Helping Hand', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '1200.00', 'width' => '14.00', 'length' => '14.00', 'height' => '26.00', 'weight' => '315.00', 'thumb' => '1656304349.jpg', 'created_at' => '2022-06-27 04:32:30', 'updated_at' => '2022-06-27 04:32:30', 'equipment_type_id' => '14'), + array('id' => '1118', 'code' => '', 'title' => 'Soldering Tip Cleaner', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '490.00', 'width' => '7.50', 'length' => '8.50', 'height' => '7.50', 'weight' => '120.00', 'thumb' => '1658317433.jpg', 'created_at' => '2022-07-20 11:43:53', 'updated_at' => '2022-07-20 11:43:53', 'equipment_type_id' => '14'), + array('id' => '1119', 'code' => '', 'title' => 'Soldering Station', 'brand' => 'Tenma', 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'High-performance dual-core ceramic heater +The temperature read out in °C and °F +Simulate bar indicating the heating up status +Buttons (1, 2, 3) for pre-setting or switching frequently used temperature +Heating element malfunction alert', 'description' => 'ESD safe thermo-control anti-static digital soldering station with LCD display.', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => '60.00', 'price' => '0.00', 'width' => '16.40', 'length' => '12.00', 'height' => '9.00', 'weight' => '1800.00', 'thumb' => '1658317668.jpg', 'created_at' => '2022-07-20 11:46:57', 'updated_at' => '2022-07-20 11:47:49', 'equipment_type_id' => '14'), + + // Safety Equipment Rack + array('id' => '1120', 'code' => '', 'title' => 'Face Shield', 'brand' => 'Ingco', 'productCode' => 'HFSPC01', 'quantity' => '2', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '1100.00', 'width' => '30.00', 'length' => '36.00', 'height' => '20.00', 'weight' => '275.00', 'thumb' => '1656163393.jpg', 'created_at' => '2022-06-25 13:23:13', 'updated_at' => '2022-06-25 13:23:13', 'equipment_type_id' => '13'), + array('id' => '1121', 'code' => '', 'title' => 'Ear Muff', 'brand' => 'Ingco', 'productCode' => 'HEM01', 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '1300.00', 'width' => '9.00', 'length' => '23.00', 'height' => '20.00', 'weight' => '185.00', 'thumb' => '1656163947.jpg', 'created_at' => '2022-06-25 13:31:31', 'updated_at' => '2022-06-25 13:32:27', 'equipment_type_id' => '13'), + array('id' => '1122', 'code' => '', 'title' => 'Safety Goggle', 'brand' => 'Ingco', 'productCode' => 'HSG05', 'quantity' => '3', 'specifications' => 'Conforms to ANSI Z87.1 and CE EN166', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '295.00', 'width' => '16.00', 'length' => '6.00', 'height' => '6.00', 'weight' => '40.00', 'thumb' => '1656165446.jpg', 'created_at' => '2022-06-25 13:57:26', 'updated_at' => '2022-06-27 04:29:16', 'equipment_type_id' => '13'), + array('id' => '1123', 'code' => '', 'title' => 'Fully Covered Safety Goggle', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '2', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '475.00', 'width' => '19.00', 'length' => '9.00', 'height' => '10.00', 'weight' => '110.00', 'thumb' => '1656165559.jpg', 'created_at' => '2022-06-25 13:59:19', 'updated_at' => '2022-06-27 04:26:38', 'equipment_type_id' => '13'), + array('id' => '1124', 'code' => '', 'title' => 'Respiratory Mask', 'brand' => 'Ingco', 'productCode' => 'HRS02', 'quantity' => '1', 'specifications' => 'Half face twin cartridge respirator, Industrial/trade quality, Protection against Harmful material with volume concentration <0.1%', 'description' => 'Can be used as a mask when working with chemicals and dust', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '2610.00', 'width' => '18.00', 'length' => '10.00', 'height' => '12.00', 'weight' => '435.00', 'thumb' => '1629632619.jpg', 'created_at' => '2021-08-22 11:43:40', 'updated_at' => '2021-08-22 11:43:57', 'equipment_type_id' => '13'), + array('id' => '1125', 'code' => '', 'title' => 'Dust Mask', 'brand' => 'Ingco', 'productCode' => 'HDM01', 'quantity' => '10', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '150.00', 'width' => '20.00', 'length' => '16.00', 'height' => '5.00', 'weight' => '15.00', 'thumb' => '1656164125.jpg', 'created_at' => '2022-06-25 13:35:25', 'updated_at' => '2022-06-27 04:36:44', 'equipment_type_id' => '13'), + array('id' => '1126', 'code' => '', 'title' => 'Mechanic Glove', 'brand' => 'Ingco', 'productCode' => 'HGMG01', 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '1150.00', 'width' => '12.00', 'length' => '24.00', 'height' => '2.00', 'weight' => '75.00', 'thumb' => '1656164543.jpg', 'created_at' => '2022-06-25 13:42:23', 'updated_at' => '2022-06-25 13:42:23', 'equipment_type_id' => '13'), + array('id' => '1127', 'code' => '', 'title' => 'Nitrile Gloves', 'brand' => 'Ingco', 'productCode' => 'HGNG01', 'quantity' => '3', 'specifications' => 'XL', 'description' => NULL, 'instructions' => 'Use for oil environment (less oil)worker etc. +Nitrile coated palm, smooth and rough-texture palm finish.', 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '350.00', 'width' => '15.00', 'length' => '25.00', 'height' => '2.00', 'weight' => '45.00', 'thumb' => '1656164691.jpg', 'created_at' => '2022-06-25 13:44:51', 'updated_at' => '2022-06-25 13:44:51', 'equipment_type_id' => '13'), + array('id' => '1128', 'code' => '', 'title' => 'Cut Resistant Gloves', 'brand' => 'Ingco', 'productCode' => 'HGCG01', 'quantity' => '3', 'specifications' => NULL, 'description' => 'Use for timber and glass cutting worker, heavy sharp objects carriers, etc', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '600.00', 'width' => '15.00', 'length' => '25.00', 'height' => '2.00', 'weight' => '70.00', 'thumb' => '1656164896.jpg', 'created_at' => '2022-06-25 13:48:16', 'updated_at' => '2022-06-25 13:48:26', 'equipment_type_id' => '13'), + array('id' => '1129', 'code' => '', 'title' => 'General Purpose Gloves', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '3', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '165.00', 'width' => '15.00', 'length' => '24.00', 'height' => '2.00', 'weight' => '40.00', 'thumb' => '1656165681.jpg', 'created_at' => '2022-06-25 14:01:21', 'updated_at' => '2022-06-27 04:30:07', 'equipment_type_id' => '13'), + array('id' => '1130', 'code' => '', 'title' => 'Safety Boots', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '2', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '1500.00', 'width' => '22.00', 'length' => '30.00', 'height' => '36.00', 'weight' => '1800.00', 'thumb' => '1656165870.jpg', 'created_at' => '2022-06-25 14:04:30', 'updated_at' => '2022-06-27 04:34:11', 'equipment_type_id' => '13'), + + // Power Tools + array('id' => '1140', 'code' => '', 'title' => 'Impact Drill', 'brand' => 'Ingco', 'productCode' => 'ID6538', 'quantity' => '1', 'specifications' => 'Input power: 650W +No-load speed:0-2700rpm +Max.drilling capacity:13mm +Variable speed control +Forward/Reverse switch +Hammer function', 'description' => NULL, 'instructions' => 'https://www.youtube.com/watch?v=eNp1cVh_et0', 'isElectrical' => '0', 'powerRating' => '650.00', 'price' => '6775.00', 'width' => '7.00', 'length' => '30.00', 'height' => '23.00', 'weight' => '1800.00', 'thumb' => '1655833803.jpg', 'created_at' => '2022-06-21 17:49:00', 'updated_at' => '2022-06-22 07:09:32', 'equipment_type_id' => '12'), + array('id' => '1141', 'code' => '', 'title' => 'Angle Grinder', 'brand' => 'Ingco', 'productCode' => 'AG8006', 'quantity' => '1', 'specifications' => 'Input power: 800W +No-load speed: 12000rpm +Disc diameter: 115mm +Spindle thread: M14', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => '800.00', 'price' => '7950.00', 'width' => '8.00', 'length' => '28.00', 'height' => '8.00', 'weight' => '1600.00', 'thumb' => '1655834032.jpg', 'created_at' => '2022-06-21 17:53:52', 'updated_at' => '2022-06-22 07:10:16', 'equipment_type_id' => '12'), + array('id' => '1142', 'code' => '', 'title' => 'Cordless Drill', 'brand' => 'DiTEC', 'productCode' => 'DT-CD1012', 'quantity' => '1', 'specifications' => '12V, 25Nm, Max. drilling capacity: 10mm, 1 battery with accessories', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '12500.00', 'width' => '22.00', 'length' => '22.00', 'height' => '8.00', 'weight' => '950.00', 'thumb' => '1655834223.jpg', 'created_at' => '2022-06-21 17:57:03', 'updated_at' => '2022-06-27 04:00:23', 'equipment_type_id' => '12'), + array('id' => '1143', 'code' => '', 'title' => 'Mini Grinder', 'brand' => 'Ingco', 'productCode' => 'MG1309', 'quantity' => '1', 'specifications' => NULL, 'description' => 'No-load speed:10000-32000rpm +Collet size:3.2mm +Variable speed control +With 1pcs flexible shaft +With 52pcs accessories', 'instructions' => NULL, 'isElectrical' => '1', 'powerRating' => '130.00', 'price' => '6350.00', 'width' => '7.00', 'length' => '27.00', 'height' => '7.00', 'weight' => '650.00', 'thumb' => '1656159940.jpg', 'created_at' => '2022-06-25 12:25:40', 'updated_at' => '2022-06-27 03:53:38', 'equipment_type_id' => '12'), + array('id' => '1144', 'code' => '', 'title' => 'Heat Gun', 'brand' => 'Ingco', 'productCode' => 'HG200028-1', 'quantity' => '1', 'specifications' => 'Temperature: 50C/50-630°C/50-630°C +Airflow: 200-500L/min /200-500L/min / 500 L/min +Adjustable temperature with LCD display for precise control +With 1pcs scraper and 4pcs nozzles +With 1pcs 60mm putty trowel', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '1', 'powerRating' => '2000.00', 'price' => '9500.00', 'width' => '9.00', 'length' => '29.00', 'height' => '21.00', 'weight' => '650.00', 'thumb' => '1656160114.jpg', 'created_at' => '2022-06-25 12:28:34', 'updated_at' => '2022-06-27 03:54:39', 'equipment_type_id' => '12'), + + + array('id' => '1145', 'code' => '', 'title' => 'Hot Glue Gun', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '2', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '1', 'powerRating' => '60.00', 'price' => '750.00', 'width' => '17.00', 'length' => '3.50', 'height' => '25.00', 'weight' => '200.00', 'thumb' => '1657297587.jpg', 'created_at' => '2022-06-25 12:28:34', 'updated_at' => '2022-07-08 09:01:11', 'equipment_type_id' => '12'), + + + // Bits and Power Tool Accessories + array('id' => '1150', 'code' => '', 'title' => 'Hole Saw Set', 'brand' => 'BOSHICHI', 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'Support only with wood and plastic materials, Induction Hardened Steel, Sizes: 2-1/8", 2", 1-1/2", 1-1/4"', 'description' => 'Used to drill large holes', 'instructions' => 'Need to set the saw blade into the mandred using the hex key before use. Use the drill at medium speed.', 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '450.00', 'width' => '10.00', 'length' => '14.00', 'height' => '3.50', 'weight' => '190.00', 'thumb' => '1629633859.jpg', 'created_at' => '2021-08-22 12:04:19', 'updated_at' => '2021-08-22 12:05:28', 'equipment_type_id' => '22'), + array('id' => '1151', 'code' => '', 'title' => 'Screw Extractor Set', 'brand' => 'Ingco', 'productCode' => 'ASE001', 'quantity' => '1', 'specifications' => 'Hardness: 48~52HRC Coarse thread +Size #1, #2, #3, #4, #5', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '2400.00', 'width' => '4.00', 'length' => '9.50', 'height' => '1.50', 'weight' => '100.00', 'thumb' => '1656161376.jpg', 'created_at' => '2022-06-25 12:49:36', 'updated_at' => '2022-06-27 04:03:30', 'equipment_type_id' => '29'), + array('id' => '1152', 'code' => '', 'title' => 'Metal Drill Bits Set', 'brand' => 'Ingco', 'productCode' => 'AKD1055', 'quantity' => '2', 'specifications' => 'Size : 2, 3, 4, 5, 6, 8 mm', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '550.00', 'width' => '6.00', 'length' => '17.00', 'height' => '2.00', 'weight' => '120.00', 'thumb' => '1656161450.jpg', 'created_at' => '2022-06-25 12:50:50', 'updated_at' => '2022-06-27 03:59:21', 'equipment_type_id' => '29'), + array('id' => '1153', 'code' => '', 'title' => 'Masonry Drill Bits set', 'brand' => 'Ronix', 'productCode' => 'RH-5587', 'quantity' => '1', 'specifications' => 'Sizes: 4,5,6,8,10', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '880.00', 'width' => '5.50', 'length' => '16.00', 'height' => '2.00', 'weight' => '350.00', 'thumb' => '1658317272.jpg', 'created_at' => '2022-07-20 11:41:12', 'updated_at' => '2022-07-20 11:41:12', 'equipment_type_id' => '29'), + + array('id' => '1160', 'code' => '', 'title' => 'Opener Tool Kit', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => '3 different pcs that can be used to open various types of plastic casings without damaging to the case.', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '250.00', 'width' => '1.00', 'length' => '16.00', 'height' => '3.50', 'weight' => '30.00', 'thumb' => '1656160593.jpg', 'created_at' => '2022-06-25 12:36:33', 'updated_at' => '2022-06-27 03:56:09', 'equipment_type_id' => '11'), + array('id' => '1161', 'code' => '', 'title' => 'Dual-end Spudger Opening Tool', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => 'A tool that can be used to open various types of plastic casings without damaging to the case.', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '290.00', 'width' => '1.00', 'length' => '15.00', 'height' => '1.00', 'weight' => '15.00', 'thumb' => '1656160767.jpg', 'created_at' => '2022-06-25 12:39:27', 'updated_at' => '2022-06-27 03:56:54', 'equipment_type_id' => '11'), + array('id' => '1162', 'code' => '', 'title' => 'Hook Cutting Tool', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '1', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '350.00', 'width' => '4.50', 'length' => '16.50', 'height' => '1.50', 'weight' => '40.00', 'thumb' => '1656161832.jpg', 'created_at' => '2022-06-25 12:57:12', 'updated_at' => '2022-06-27 04:01:42', 'equipment_type_id' => '22'), + array('id' => '1163', 'code' => '', 'title' => 'Step Drill Bit', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'HSS Titanium Step Drill Bit', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '1', 'powerRating' => NULL, 'price' => '2134.00', 'width' => '3.50', 'length' => '10.00', 'height' => '3.50', 'weight' => '145.00', 'thumb' => '1656302843.jpg', 'created_at' => '2022-06-27 04:07:23', 'updated_at' => '2022-06-27 04:07:23', 'equipment_type_id' => '29'), + array('id' => '1164 ', 'code' => '', 'title' => 'Deburring External Chamfer Tool', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'Color: Black +Shaft Hex', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '380.00', 'width' => '3.00', 'length' => '3.00', 'height' => '5.50', 'weight' => '35.00', 'thumb' => '1656303779.jpg', 'created_at' => '2022-06-27 04:22:59', 'updated_at' => '2022-06-27 04:22:59', 'equipment_type_id' => '29'), + + // Clamps Rack + array('id' => '1170', 'code' => '', 'title' => '2" G Clamp', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '2', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '400.00', 'width' => '6.00', 'length' => '12.00', 'height' => '1.50', 'weight' => '110.00', 'thumb' => '1656162232.jpg', 'created_at' => '2022-06-25 13:03:52', 'updated_at' => '2022-06-27 04:01:00', 'equipment_type_id' => '21'), + array('id' => '1171', 'code' => '', 'title' => 'G Clamp 6"', 'brand' => 'Ingco', 'productCode' => 'HGC0106', 'quantity' => '2', 'specifications' => 'Size:6"/150mm +Body malleable cast iron +T-shaped thread', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '1200.00', 'width' => '16', 'length' => '26', 'height' => '3.5', 'weight' => '1500', 'thumb' => '1656166067.jpg', 'created_at' => '2022-06-25 14:07:47', 'updated_at' => '2022-06-25 14:07:47', 'equipment_type_id' => '21'), + array('id' => '1172', 'code' => '', 'title' => 'Quick Grip Clamp 4"', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '4', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '350.00', 'width' => '11.00', 'length' => '20.00', 'height' => '1.50', 'weight' => '70.00', 'thumb' => '1656162870.jpg', 'created_at' => '2022-06-25 13:04:37', 'updated_at' => '2022-06-25 13:28:48', 'equipment_type_id' => '21'), + array('id' => '1173', 'code' => '', 'title' => 'Quick Grip Clamp 8"', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '2', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '850.00', 'width' => '21.00', 'length' => '37.00', 'height' => '3.00', 'weight' => '485.00', 'thumb' => '1656162312.jpg', 'created_at' => '2022-06-25 13:05:13', 'updated_at' => '2022-06-27 04:25:26', 'equipment_type_id' => '21'), + array('id' => '1174', 'code' => '', 'title' => 'Quick Grip Clamp 12"', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '2', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '1050.00', 'width' => '21.00', 'length' => '48.00', 'height' => '3.00', 'weight' => '560.00', 'thumb' => '1656162344.jpg', 'created_at' => '2022-06-25 13:05:44', 'updated_at' => '2022-06-25 13:26:09', 'equipment_type_id' => '21'), + array('id' => '1175', 'code' => '', 'title' => 'Spring Clamp 4"', 'brand' => 'WOKIN', 'productCode' => NULL, 'quantity' => '4', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '375.00', 'width' => '12.00', 'length' => '16.00', 'height' => '3.50', 'weight' => '85.00', 'thumb' => '1656162480.jpg', 'created_at' => '2022-06-25 13:08:00', 'updated_at' => '2022-06-25 13:24:23', 'equipment_type_id' => '21'), + + array('id' => '1176', 'code' => '', 'title' => 'Self Healing Cutting Mat', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '2', 'specifications' => NULL, 'description' => NULL, 'instructions' => 'https://www.firstmats.co.uk/blogs/buying-guides/how-do-self-healing-cutting-mats-work', 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '3750.00', 'width' => '42.00', 'length' => '29.70', 'height' => '0.50', 'weight' => '300.00', 'thumb' => '1663871757.jpg', 'created_at' => '2022-09-22 18:35:58', 'updated_at' => '2022-09-22 18:35:58', 'equipment_type_id' => '31'), + array('id' => '1177', 'code' => '', 'title' => 'Brush', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '3', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '110.00', 'width' => '6.00', 'length' => '24.00', 'height' => '10.00', 'weight' => '350.00', 'thumb' => '1663872187.jpg', 'created_at' => '2022-09-22 18:43:08', 'updated_at' => '2022-09-22 18:43:08', 'equipment_type_id' => '31'), + + array('id' => '1178', 'code' => '', 'title' => 'Speaker Test Kit', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '2', 'specifications' => NULL, 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '1', 'powerRating' => NULL, 'price' => '0.00', 'width' => '9.00', 'length' => '9.00', 'height' => '4.50', 'weight' => '150.00', 'thumb' => '1663872508.jpg', 'created_at' => '2022-09-22 18:48:28', 'updated_at' => '2022-09-22 18:48:28', 'equipment_type_id' => '30'), + array('id' => '1179', 'code' => '', 'title' => 'Breadboard Kit', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '3', 'specifications' => NULL, 'description' => 'Custom-made Breadboard unit', 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '0.00', 'width' => '25.00', 'length' => '18.00', 'height' => '2.50', 'weight' => '200.00', 'thumb' => '1663872871.jpg', 'created_at' => '2022-09-22 18:54:31', 'updated_at' => '2022-09-22 18:54:31', 'equipment_type_id' => '30'), + array('id' => '1180', 'code' => '', 'title' => 'Universal Bench Vise', 'brand' => NULL, 'productCode' => NULL, 'quantity' => '1', 'specifications' => 'Maximum clamping capacity of the fixed clip: 50mm +The maximum jaw clamping capacity: 55mm +Jaw width: 76MM', 'description' => NULL, 'instructions' => NULL, 'isElectrical' => '0', 'powerRating' => NULL, 'price' => '2800.00', 'width' => '10.00', 'length' => '16.00', 'height' => '24.00', 'weight' => '860.00', 'thumb' => '1664414610.jpg', 'created_at' => '2022-09-29 01:23:31', 'updated_at' => '2022-09-29 01:23:31', 'equipment_type_id' => '21') ]; /** diff --git a/database/seeders/EquipmentTypeSeeder.php b/database/seeders/EquipmentTypeSeeder.php old mode 100644 new mode 100755 index de36f2b9..30b41037 --- a/database/seeders/EquipmentTypeSeeder.php +++ b/database/seeders/EquipmentTypeSeeder.php @@ -8,21 +8,26 @@ class EquipmentTypeSeeder extends Seeder { protected $data = [ - array('id' => '11', 'code' => '', 'parent_id' => NULL, 'title' => 'Hand Tools', 'subtitle' => NULL, 'description' => 'Nonelectrical tools that used to make physical changes to objects.', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-08-04 15:25:03'), - array('id' => '12', 'code' => '', 'parent_id' => NULL, 'title' => 'Power Tools', 'subtitle' => NULL, 'description' => 'Electrical tools and machines that used to make physical changes to objects.', 'thumb' => NULL, 'created_at' => '2021-08-04 15:24:54', 'updated_at' => '2021-08-04 15:24:54'), - array('id' => '13', 'code' => '', 'parent_id' => NULL, 'title' => 'Safety Equipment', 'subtitle' => NULL, 'description' => 'Wearable equipment which are used for the protection of life and to avoid injuries.', 'thumb' => NULL, 'created_at' => '2021-08-04 15:27:16', 'updated_at' => '2021-08-04 15:27:16'), - array('id' => '14', 'code' => '', 'parent_id' => NULL, 'title' => 'Soldering Tools', 'subtitle' => NULL, 'description' => 'Tools that are related to soldering', 'thumb' => NULL, 'created_at' => '2021-08-04 16:10:20', 'updated_at' => '2021-08-04 16:10:20'), - array('id' => '15', 'code' => '', 'parent_id' => NULL, 'title' => 'Measuring Instruments', 'subtitle' => 'Physical Measurements', 'description' => 'Tools that are used to take measurements', 'thumb' => NULL, 'created_at' => '2021-08-04 16:11:20', 'updated_at' => '2021-08-04 16:11:35'), - array('id' => '16', 'code' => '', 'parent_id' => NULL, 'title' => 'Prototyping Machines', 'subtitle' => NULL, 'description' => 'Machines that are used to fabricate things', 'thumb' => NULL, 'created_at' => '2021-08-04 16:12:45', 'updated_at' => '2021-08-04 16:12:45'), + array('id' => '11', 'code' => '', 'parent_id' => NULL, 'title' => 'Hand Tools', 'subtitle' => NULL, 'description' => 'Nonelectrical tools that used to make physical changes to objects.', 'thumb' => '1656746788.jpg', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-08-04 15:25:03'), + array('id' => '12', 'code' => '', 'parent_id' => NULL, 'title' => 'Power Tools', 'subtitle' => NULL, 'description' => 'Electrical tools and machines that used to make physical changes to objects.', 'thumb' => '1656746798.jpg', 'created_at' => '2021-08-04 15:24:54', 'updated_at' => '2021-08-04 15:24:54'), + array('id' => '13', 'code' => '', 'parent_id' => NULL, 'title' => 'Safety Equipment', 'subtitle' => NULL, 'description' => 'Wearable equipment which are used for the protection of life and to avoid injuries.', 'thumb' => '1656746809.jpg', 'created_at' => '2021-08-04 15:27:16', 'updated_at' => '2021-08-04 15:27:16'), + array('id' => '14', 'code' => '', 'parent_id' => NULL, 'title' => 'Soldering Tools', 'subtitle' => NULL, 'description' => 'Tools that are related to soldering', 'thumb' => '1656746819.jpg', 'created_at' => '2021-08-04 16:10:20', 'updated_at' => '2021-08-04 16:10:20'), + array('id' => '15', 'code' => '', 'parent_id' => NULL, 'title' => 'Measuring Instruments', 'subtitle' => 'Physical Measurements', 'description' => 'Tools that are used to take measurements', 'thumb' => '1656746829.png', 'created_at' => '2021-08-04 16:11:20', 'updated_at' => '2021-08-04 16:11:35'), array('id' => '17', 'code' => '', 'parent_id' => '11', 'title' => 'Screwdrivers', 'subtitle' => NULL, 'description' => 'A screwdriver is a tool, manual or powered, used for driving screws. A typical simple screwdriver has a handle and a shaft, ending in a tip the user puts into the screw head before turning the handle.', 'thumb' => '1629005722.jpg', 'created_at' => '2021-08-15 05:33:05', 'updated_at' => '2021-08-15 05:45:03'), array('id' => '18', 'code' => '', 'parent_id' => '11', 'title' => 'Pliers', 'subtitle' => NULL, 'description' => 'Pliers are a hand tools used to hold objects firmly', 'thumb' => '1629006269.jpg', 'created_at' => '2021-08-15 05:44:29', 'updated_at' => '2021-08-15 05:44:29'), - array('id' => '19', 'code' => '', 'parent_id' => '11', 'title' => 'Wrenches', 'subtitle' => NULL, 'description' => 'A wrench or spanner is a tool used to provide grip and mechanical advantage in applying torque to turn objects', 'thumb' => '1629006425.jpg', 'created_at' => '2021-08-15 05:47:05', 'updated_at' => '2021-08-15 05:47:14'), - array('id' => '20', 'code' => '', 'parent_id' => '11', 'title' => 'Half Inch Sockets', 'subtitle' => '1/2" Sockets', 'description' => 'Half Inch Sockets are a range of metric sockets that come with a 0.5-inch box type head. There are a set of sockets and accessories available in this family of tools.', 'thumb' => '1629006847.jpg', 'created_at' => '2021-08-15 05:53:12', 'updated_at' => '2021-08-15 05:54:07'), + array('id' => '19', 'code' => '', 'parent_id' => '27', 'title' => 'Combination Wrenches', 'subtitle' => NULL, 'description' => 'A wrench or spanner is a tool used to provide grip and mechanical advantage in applying torque to turn objects', 'thumb' => '1655880773.jpg', 'created_at' => '2021-08-15 05:47:05', 'updated_at' => '2022-06-22 06:58:50'), + array('id' => '20', 'code' => '', 'parent_id' => '28', 'title' => 'Half Inch Sockets', 'subtitle' => '1/2" Sockets', 'description' => 'Half Inch Sockets are a range of metric sockets that come with a 0.5-inch box type head. There are a set of sockets and accessories available in this family of tools.', 'thumb' => '1655880450.jpg', 'created_at' => '2021-08-15 05:53:12', 'updated_at' => '2022-06-22 07:00:02'), array('id' => '21', 'code' => '', 'parent_id' => '11', 'title' => 'Clamps', 'subtitle' => NULL, 'description' => 'A brace, band, or clasp for strengthening or holding things together', 'thumb' => '1629008372.jpg', 'created_at' => '2021-08-15 06:19:33', 'updated_at' => '2021-08-15 06:19:33'), array('id' => '22', 'code' => '', 'parent_id' => '11', 'title' => 'Cutters and Saws', 'subtitle' => NULL, 'description' => 'Used to cut or separate the workpiece', 'thumb' => '1629008575.jpg', 'created_at' => '2021-08-15 06:22:55', 'updated_at' => '2021-08-15 07:33:08'), array('id' => '23', 'code' => '', 'parent_id' => '11', 'title' => 'Hammers', 'subtitle' => NULL, 'description' => 'Hammer is a standard hand tool that is mostly used for striking objects', 'thumb' => '1629008659.jpg', 'created_at' => '2021-08-15 06:24:19', 'updated_at' => '2021-08-15 06:24:19'), - array('id' => '24', 'code' => '', 'parent_id' => '11', 'title' => 'Quarter Inch Sockets', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL, 'created_at' => '2021-08-17 11:26:40', 'updated_at' => '2021-08-17 11:26:40'), - array('id' => '25', 'code' => '', 'parent_id' => '11', 'title' => 'Files', 'subtitle' => NULL, 'description' => 'A file is a tool used to remove fine amounts of material from a workpiece', 'thumb' => '1629630206.jpg', 'created_at' => '2021-08-22 11:03:26', 'updated_at' => '2021-08-22 11:03:26') + array('id' => '24', 'code' => '', 'parent_id' => '28', 'title' => 'Quarter Inch Sockets', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL, 'created_at' => '2021-08-17 11:26:40', 'updated_at' => '2022-06-22 07:00:17'), + array('id' => '25', 'code' => '', 'parent_id' => '11', 'title' => 'Files', 'subtitle' => NULL, 'description' => 'A file is a tool used to remove fine amounts of material from a workpiece', 'thumb' => '1629630206.jpg', 'created_at' => '2021-08-22 11:03:26', 'updated_at' => '2021-08-22 11:03:26'), + array('id' => '26', 'code' => '', 'parent_id' => '27', 'title' => 'Double Open Wrenches', 'subtitle' => NULL, 'description' => 'A wrench or spanner is a tool used to provide grip and mechanical advantage in applying torque to turn objects', 'thumb' => '1655880526.jpg', 'created_at' => '2021-08-15 05:47:05', 'updated_at' => '2022-06-22 06:58:08'), + array('id' => '27', 'code' => '', 'parent_id' => '11', 'title' => 'Wrenches', 'subtitle' => NULL, 'description' => 'A wrench or spanner is a tool used to provide grip and mechanical advantage in applying torque to turn objects', 'thumb' => '1655880945.jpg', 'created_at' => '2022-06-22 06:55:45', 'updated_at' => '2022-06-22 06:55:45'), + array('id' => '28', 'code' => '', 'parent_id' => '11', 'title' => 'Sockets', 'subtitle' => NULL, 'description' => 'Sockets are tools used to tighten mechanical fasteners. They fit over the head of the fastener to provide torque.', 'thumb' => '1655881186.jpg', 'created_at' => '2022-06-22 06:59:46', 'updated_at' => '2022-06-22 07:00:48'), + array('id' => '29', 'code' => '', 'parent_id' => '12', 'title' => 'Tool Accessories', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL, 'created_at' => '2022-06-25 12:51:37', 'updated_at' => '2022-06-25 12:51:37'), + array('id' => '30', 'code' => '', 'parent_id' => NULL, 'title' => 'Custom Made Equipment', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL, 'created_at' => '2022-09-22 18:28:59', 'updated_at' => '2022-09-22 18:28:59'), + array('id' => '31', 'code' => '', 'parent_id' => NULL, 'title' => 'Other', 'subtitle' => NULL, 'description' => NULL, 'thumb' => NULL, 'created_at' => '2022-09-22 18:29:55', 'updated_at' => '2022-09-22 18:29:55') ]; /** diff --git a/database/seeders/ItemLocationsSeeder.php b/database/seeders/ItemLocationsSeeder.php new file mode 100755 index 00000000..f16dd35e --- /dev/null +++ b/database/seeders/ItemLocationsSeeder.php @@ -0,0 +1,218 @@ + '13', 'item_id' => 'EQ/22/1001', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/22/1002', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/11/1003', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/23/1004', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/23/1005', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/11/1006', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/11/1007', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/27/1008', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/15/1009', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '6', 'item_id' => 'EQ/15/1009', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '5', 'item_id' => 'EQ/22/1010', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '6', 'item_id' => 'EQ/22/1010', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/22/1010', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/15/1011', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '6', 'item_id' => 'EQ/15/1011', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/15/1012', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/15/1013', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '6', 'item_id' => 'EQ/15/1013', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/18/1014', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/18/1015', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/18/1016', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '6', 'item_id' => 'EQ/18/1016', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '5', 'item_id' => 'EQ/18/1016', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '4', 'item_id' => 'EQ/18/1016', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/22/1017', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/22/1018', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/17/1019', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '13', 'item_id' => 'EQ/17/1020', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/25/1021', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/25/1022', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/20/1023', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/27/1024', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/19/1025', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/19/1026', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/19/1027', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/19/1028', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/19/1029', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '13', 'item_id' => 'EQ/19/1030', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/19/1031', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/19/1032', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/19/1033', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/19/1034', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/19/1035', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/19/1036', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/20/1037', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '31', 'item_id' => 'EQ/20/1038', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '31', 'item_id' => 'EQ/20/1039', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '31', 'item_id' => 'EQ/20/1040', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '31', 'item_id' => 'EQ/20/1041', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '31', 'item_id' => 'EQ/20/1042', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '31', 'item_id' => 'EQ/20/1043', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '31', 'item_id' => 'EQ/20/1044', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '31', 'item_id' => 'EQ/20/1045', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '31', 'item_id' => 'EQ/20/1046', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '31', 'item_id' => 'EQ/20/1047', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '31', 'item_id' => 'EQ/20/1048', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '31', 'item_id' => 'EQ/20/1049', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '31', 'item_id' => 'EQ/20/1050', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '31', 'item_id' => 'EQ/20/1051', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '31', 'item_id' => 'EQ/20/1052', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '31', 'item_id' => 'EQ/20/1053', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '31', 'item_id' => 'EQ/20/1054', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '31', 'item_id' => 'EQ/20/1055', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '31', 'item_id' => 'EQ/20/1056', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '31', 'item_id' => 'EQ/20/1057', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '31', 'item_id' => 'EQ/20/1058', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '31', 'item_id' => 'EQ/20/1059', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '32', 'item_id' => 'EQ/17/1060', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '32', 'item_id' => 'EQ/17/1061', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '32', 'item_id' => 'EQ/17/1062', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '32', 'item_id' => 'EQ/17/1063', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '32', 'item_id' => 'EQ/17/1064', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '32', 'item_id' => 'EQ/17/1065', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '32', 'item_id' => 'EQ/17/1066', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '32', 'item_id' => 'EQ/17/1067', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '32', 'item_id' => 'EQ/17/1068', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '32', 'item_id' => 'EQ/17/1069', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '32', 'item_id' => 'EQ/17/1070', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '32', 'item_id' => 'EQ/17/1071', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '32', 'item_id' => 'EQ/17/1072', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '32', 'item_id' => 'EQ/17/1073', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '32', 'item_id' => 'EQ/17/1074', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '32', 'item_id' => 'EQ/17/1075', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '32', 'item_id' => 'EQ/24/1076', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '32', 'item_id' => 'EQ/17/1077', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '6', 'item_id' => 'EQ/17/1078', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '6', 'item_id' => 'EQ/17/1079', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '6', 'item_id' => 'EQ/17/1080', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '33', 'item_id' => 'EQ/26/1081', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '33', 'item_id' => 'EQ/26/1082', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '33', 'item_id' => 'EQ/26/1083', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '33', 'item_id' => 'EQ/26/1084', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '33', 'item_id' => 'EQ/26/1085', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '33', 'item_id' => 'EQ/26/1086', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '33', 'item_id' => 'EQ/26/1087', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '33', 'item_id' => 'EQ/26/1088', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '6', 'item_id' => 'EQ/22/1089', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '5', 'item_id' => 'EQ/22/1089', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '6', 'item_id' => 'EQ/18/1090', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '6', 'item_id' => 'EQ/22/1091', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '4', 'item_id' => 'EQ/22/1091', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '6', 'item_id' => 'EQ/15/1092', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '6', 'item_id' => 'EQ/15/1093', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '5', 'item_id' => 'EQ/17/1100', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '5', 'item_id' => 'EQ/15/1101', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '5', 'item_id' => 'EQ/15/1102', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '5', 'item_id' => 'EQ/15/1103', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '4', 'item_id' => 'EQ/22/1110', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '4', 'item_id' => 'EQ/22/1111', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '4', 'item_id' => 'EQ/22/1112', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '6', 'item_id' => 'EQ/14/1113', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '4', 'item_id' => 'EQ/14/1113', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '6', 'item_id' => 'EQ/14/1114', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '4', 'item_id' => 'EQ/14/1114', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '4', 'item_id' => 'EQ/14/1115', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '4', 'item_id' => 'EQ/14/1116', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '4', 'item_id' => 'EQ/14/1117', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '4', 'item_id' => 'EQ/14/1118', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '4', 'item_id' => 'EQ/14/1119', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '16', 'item_id' => 'EQ/13/1120', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '16', 'item_id' => 'EQ/13/1121', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '16', 'item_id' => 'EQ/13/1122', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '16', 'item_id' => 'EQ/13/1123', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '16', 'item_id' => 'EQ/13/1124', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '16', 'item_id' => 'EQ/13/1125', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '16', 'item_id' => 'EQ/13/1126', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '16', 'item_id' => 'EQ/13/1127', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '16', 'item_id' => 'EQ/13/1128', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '16', 'item_id' => 'EQ/13/1129', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '16', 'item_id' => 'EQ/13/1130', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '15', 'item_id' => 'EQ/12/1140', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '15', 'item_id' => 'EQ/12/1141', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '6', 'item_id' => 'EQ/12/1142', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '15', 'item_id' => 'EQ/12/1143', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '15', 'item_id' => 'EQ/12/1144', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '13', 'item_id' => 'EQ/22/1150', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '12', 'item_id' => 'EQ/29/1152', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '12', 'item_id' => 'EQ/29/1153', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '6', 'item_id' => 'EQ/11/1160', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '6', 'item_id' => 'EQ/11/1161', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '6', 'item_id' => 'EQ/22/1162', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '12', 'item_id' => 'EQ/29/1163', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '12', 'item_id' => 'EQ/29/1164', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '13', 'item_id' => 'EQ/21/1170', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '17', 'item_id' => 'EQ/21/1171', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '6', 'item_id' => 'EQ/21/1172', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/21/1173', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/21/1174', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '13', 'item_id' => 'EQ/21/1175', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '5', 'item_id' => 'EQ/30/1178', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '2', 'item_id' => 'EQ/30/1179', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '5', 'item_id' => 'EQ/30/1179', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '6', 'item_id' => 'EQ/31/1176', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '5', 'item_id' => 'EQ/31/1176', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '4', 'item_id' => 'EQ/31/1177', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '6', 'item_id' => 'EQ/31/1177', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '17', 'item_id' => 'EQ/31/1177', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '6', 'item_id' => 'EQ/13/1122', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '6', 'item_id' => 'EQ/13/1128', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '5', 'item_id' => 'EQ/12/1145', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '6', 'item_id' => 'EQ/12/1145', 'x' => NULL, 'y' => NULL, 'z' => NULL), + + array('location_id' => '6', 'item_id' => 'EQ/21/1180', 'x' => NULL, 'y' => NULL, 'z' => NULL), + array('location_id' => '4', 'item_id' => 'EQ/13/1123', 'x' => NULL, 'y' => NULL, 'z' => NULL), + ]; + + /** + * Run the database seeds. + * + * @return void + */ + public function run() + { + foreach ($this->data as $index => $setting) { + $result = DB::table('item_locations')->insert($setting); + + if (!$result) { + $this->command->info("Insert failed at record $index."); + return; + } + } + + $this->command->info('Inserted ' . count($this->data) . ' records to item_locations table'); + } +} diff --git a/database/seeders/JobRequestsSeeder.php b/database/seeders/JobRequestsSeeder.php new file mode 100755 index 00000000..5efe0aa5 --- /dev/null +++ b/database/seeders/JobRequestsSeeder.php @@ -0,0 +1,35 @@ + '1', 'student' => '1', 'supervisor' => '1', 'student_notes' => 'This is the test A', 'supervisor_notes' => NULL, 'other_notes' => NULL, 'machine' => '2', 'material' => '1', 'status' => 'PENDING_FABRICATION', 'file' => '1655084271.zip', 'thumb' => '1655084271.jpg', 'requested_time' => '2022-06-13 01:37:51', 'approved_time' => NULL, 'scheduled_time' => NULL, 'started_time' => NULL, 'completed_time' => NULL, 'finished_time' => NULL, 'material_usage' => '0.00', 'machine_time' => '0', 'created_at' => '2022-06-13 01:37:51', 'updated_at' => '2022-06-13 01:37:51'), + array('id' => '2', 'student' => '1', 'supervisor' => '1', 'student_notes' => 'This is the test B', 'supervisor_notes' => NULL, 'other_notes' => NULL, 'machine' => '2', 'material' => '1', 'status' => 'WAITING_SUPERVISOR_APPROVAL', 'file' => '1655084272.zip', 'thumb' => '1655084272.jpg', 'requested_time' => '2022-06-13 01:37:51', 'approved_time' => NULL, 'scheduled_time' => NULL, 'started_time' => NULL, 'completed_time' => NULL, 'finished_time' => NULL, 'material_usage' => '0.00', 'machine_time' => '0', 'created_at' => '2022-06-13 01:37:51', 'updated_at' => '2022-06-13 01:37:51'), + array('id' => '3', 'student' => '1', 'supervisor' => '1', 'student_notes' => 'This is the test C', 'supervisor_notes' => NULL, 'other_notes' => NULL, 'machine' => '2', 'material' => '1', 'status' => 'PENDING', 'file' => '1655084273.zip', 'thumb' => '1655084273.jpg', 'requested_time' => '2022-06-13 01:37:51', 'approved_time' => NULL, 'scheduled_time' => NULL, 'started_time' => NULL, 'completed_time' => NULL, 'finished_time' => NULL, 'material_usage' => '0.00', 'machine_time' => '0', 'created_at' => '2022-06-13 01:37:51', 'updated_at' => '2022-06-13 01:37:51') + ]; + + public function run() + { + foreach ($this->data as $index => $setting) { + $result = DB::table('job_requests')->insert($setting); + + if (!$result) { + $this->command->info("Insert failed at record $index."); + return; + } + } + + $this->command->info('Inserted ' . count($this->data) . ' records to job_requests table'); + } +} diff --git a/database/seeders/LocationsSeeder.php b/database/seeders/LocationsSeeder.php new file mode 100755 index 00000000..551262d2 --- /dev/null +++ b/database/seeders/LocationsSeeder.php @@ -0,0 +1,68 @@ + '1', 'location' => 'MakerSpace', 'parent_location' => NULL, 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => NULL, 'updated_at' => NULL), + array('id' => '2', 'location' => 'Measuring Station A', 'parent_location' => '1', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:47:50', 'updated_at' => '2022-07-09 17:47:50'), + array('id' => '3', 'location' => 'Measuring Station B', 'parent_location' => '1', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:47:59', 'updated_at' => '2022-07-09 17:47:59'), + array('id' => '4', 'location' => 'Soldering Station', 'parent_location' => '1', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:48:14', 'updated_at' => '2022-07-09 17:48:14'), + array('id' => '5', 'location' => 'Testing Station', 'parent_location' => '1', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:48:25', 'updated_at' => '2022-07-09 17:48:25'), + array('id' => '6', 'location' => 'Assembling Station', 'parent_location' => '1', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:48:42', 'updated_at' => '2022-07-09 17:48:42'), + array('id' => '7', 'location' => '3D Printer Station', 'parent_location' => '1', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:49:22', 'updated_at' => '2022-07-09 17:49:22'), + array('id' => '8', 'location' => 'CNC Station', 'parent_location' => '1', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:49:35', 'updated_at' => '2022-07-09 17:49:35'), + array('id' => '9', 'location' => 'Component Drawer Rack', 'parent_location' => '1', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:50:09', 'updated_at' => '2022-07-09 17:50:09'), + array('id' => '10', 'location' => 'Machine Room', 'parent_location' => '1', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:49:04', 'updated_at' => '2022-07-09 17:49:04'), + array('id' => '11', 'location' => 'Drawer Rack', 'parent_location' => '5', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:55:29', 'updated_at' => '2022-07-09 17:55:29'), + array('id' => '12', 'location' => 'Wall Rack', 'parent_location' => '10', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:55:51', 'updated_at' => '2022-07-09 17:55:51'), + array('id' => '13', 'location' => 'Tools Board', 'parent_location' => '10', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:56:10', 'updated_at' => '2022-07-09 17:56:10'), + array('id' => '14', 'location' => 'Storage Bin Rack', 'parent_location' => '10', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:56:33', 'updated_at' => '2022-07-09 17:56:33'), + array('id' => '15', 'location' => 'Power Tools Rack', 'parent_location' => '10', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:56:51', 'updated_at' => '2022-07-09 17:56:51'), + array('id' => '16', 'location' => 'Safety Equipment Rack', 'parent_location' => '10', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:57:04', 'updated_at' => '2022-07-09 17:57:04'), + array('id' => '17', 'location' => 'Table A', 'parent_location' => '10', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:57:23', 'updated_at' => '2022-07-09 17:57:23'), + array('id' => '18', 'location' => 'Table B', 'parent_location' => '10', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:57:35', 'updated_at' => '2022-07-09 17:57:35'), + array('id' => '19', 'location' => 'Drawer 01', 'parent_location' => '9', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:58:27', 'updated_at' => '2022-07-09 17:58:27'), + array('id' => '20', 'location' => 'Drawer 02', 'parent_location' => '9', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:58:27', 'updated_at' => '2022-07-09 17:58:27'), + array('id' => '21', 'location' => 'Drawer 03', 'parent_location' => '9', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:58:27', 'updated_at' => '2022-07-09 17:58:27'), + array('id' => '22', 'location' => 'Drawer 04', 'parent_location' => '9', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:58:27', 'updated_at' => '2022-07-09 17:58:27'), + array('id' => '23', 'location' => 'Drawer 05', 'parent_location' => '9', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:58:27', 'updated_at' => '2022-07-09 17:58:27'), + array('id' => '24', 'location' => 'Drawer 06', 'parent_location' => '9', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:58:27', 'updated_at' => '2022-07-09 17:58:27'), + array('id' => '25', 'location' => 'Drawer 07', 'parent_location' => '9', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:58:27', 'updated_at' => '2022-07-09 17:58:27'), + array('id' => '26', 'location' => 'Drawer 08', 'parent_location' => '9', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:58:27', 'updated_at' => '2022-07-09 17:58:27'), + array('id' => '27', 'location' => 'Drawer 09', 'parent_location' => '9', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:58:27', 'updated_at' => '2022-07-09 17:58:27'), + array('id' => '28', 'location' => 'Drawer 10', 'parent_location' => '9', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:58:27', 'updated_at' => '2022-07-09 17:58:27'), + array('id' => '29', 'location' => 'Drawer 11', 'parent_location' => '9', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:58:27', 'updated_at' => '2022-07-09 17:58:27'), + array('id' => '30', 'location' => 'Drawer 12', 'parent_location' => '9', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:58:27', 'updated_at' => '2022-07-09 17:58:27'), + array('id' => '31', 'location' => 'Half Sockets Board', 'parent_location' => '13', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:58:27', 'updated_at' => '2022-07-09 17:58:27'), + array('id' => '32', 'location' => 'Screwdriver Rack', 'parent_location' => '6', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:58:27', 'updated_at' => '2022-07-09 17:58:27'), + array('id' => '33', 'location' => 'Double Open Wrench kit', 'parent_location' => '6', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:58:27', 'updated_at' => '2022-07-09 17:58:27'), + array('id' => '34', 'location' => 'Testing Accessories Set', 'parent_location' => '5', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:58:27', 'updated_at' => '2022-07-09 17:58:27'), + array('id' => '35', 'location' => 'Power Supply Unit', 'parent_location' => '5', 'x' => NULL, 'y' => NULL, 'z' => NULL, 'created_at' => '2022-07-09 17:58:27', 'updated_at' => '2022-07-09 17:58:27'), + + ]; + + /** + * Run the database seeds. + * + * @return void + */ + public function run() + { + foreach ($this->data as $index => $setting) { + + $result = DB::table('locations')->insert($setting); + + if (!$result) { + $this->command->info("Insert failed at record $index."); + return; + } + } + $this->command->info('Inserted ' . count($this->data) . ' records to locations table'); + } +} diff --git a/database/seeders/MachinesSeeder.php b/database/seeders/MachinesSeeder.php new file mode 100755 index 00000000..780c3059 --- /dev/null +++ b/database/seeders/MachinesSeeder.php @@ -0,0 +1,34 @@ + '1', 'code' => '', 'title' => 'Makerbot Replicator', 'type' => 'FDM_3D_PRINTER', 'build_width' => '300.00', 'build_length' => '200.00', 'build_height' => '165.00', 'power' => NULL, 'thumb' => '1652269372.png', 'specifications' => 'Layer Resolution: 100 microns\nMaterial Diameter: 1.75 mm\nExtruder Compatibility: Smart Extruder+', 'status' => 'AVAILABLE', 'notes' => 'Can only print with PLA', 'lifespan' => '0.00', 'created_at' => '2022-05-11 11:42:52', 'updated_at' => '2022-05-11 11:42:52'), + array('id' => '2', 'code' => '', 'title' => 'Ender 3 Pro printer 1', 'type' => 'FDM_3D_PRINTER', 'build_width' => '300.00', 'build_length' => '300.00', 'build_height' => '400.00', 'power' => '80.00', 'thumb' => '1652269099.jpg', 'specifications' => 'Technology: FDM.\nPrint Area: 220 x 220 x 250mm.\nNozzle: 0.4mm.\nFilament: 1.75mm PLA, ABS, TPU.\nMax. Print Speed: 200mm/s.\nMax. Layer Resolution: 0.1mm.\nPrint Precision: +/-0.1mm.\nHeated Bed: Yes.', 'status' => 'NOT_AVAILABLE', 'notes' => 'Not yet received', 'lifespan' => '0.00', 'created_at' => '2022-05-11 11:38:19', 'updated_at' => '2022-05-11 11:38:19'), + ]; + + /** + * Run the database seeds. + * + * @return void + */ + public function run() + { + foreach ($this->data as $index => $setting) { + $result = DB::table('machines')->insert($setting); + + if (!$result) { + $this->command->info("Insert failed at record $index."); + return; + } + } + + $this->command->info('Inserted ' . count($this->data) . ' records to machines table'); + } +} diff --git a/database/seeders/OrderSeeder.php b/database/seeders/OrderSeeder.php new file mode 100755 index 00000000..6e3c5629 --- /dev/null +++ b/database/seeders/OrderSeeder.php @@ -0,0 +1,35 @@ +disableForeignKeys(); + + Order::factory() + ->count(50) + ->hasComponentItems(5) + ->create(); + + + $this->enableForeignKeys(); + + + } +} diff --git a/database/seeders/RawMaterialsSeeder.php b/database/seeders/RawMaterialsSeeder.php new file mode 100755 index 00000000..5f630f34 --- /dev/null +++ b/database/seeders/RawMaterialsSeeder.php @@ -0,0 +1,39 @@ + '1', 'code' => '', 'title' => 'eSUN PLA+ Gray Printer Filament', 'color' => 'Gray', 'description' => '1.75mm diameter, 1kg, Gray', 'specifications' => 'Printing Temperature 210-230 ℃\nBase Plate Temperature 45-60 ℃\nPrinting Speed 40-100 mm/s\nDensity 1.23 g/cm^3', 'quantity' => '1.00', 'unit' => 'kg', 'thumb' => '1655083181.jpg', 'availability' => 'AVAILABLE', 'notes' => NULL, 'created_at' => '2022-06-13 01:19:41', 'updated_at' => '2022-06-13 01:19:41'), + array('id' => '2', 'code' => '', 'title' => 'eSUN PLA+ White Printer Filament', 'color' => 'White', 'description' => '1.75mm diameter, 1kg, White', 'specifications' => 'Printing Temperature 210-230 ℃\nBase Plate Temperature 45-60 ℃\nPrinting Speed 40-100 mm/s\nDensity 1.23 g/cm^3', 'quantity' => '1.00', 'unit' => 'kg', 'thumb' => '1655083181.jpg', 'availability' => 'AVAILABLE', 'notes' => NULL, 'created_at' => '2022-06-13 01:19:41', 'updated_at' => '2022-06-13 01:19:41'), + array('id' => '3', 'code' => '', 'title' => 'eSUN PLA+ Black Printer Filament', 'color' => 'Black', 'description' => '1.75mm diameter, 1kg, Black', 'specifications' => 'Printing Temperature 210-230 ℃\nBase Plate Temperature 45-60 ℃\nPrinting Speed 40-100 mm/s\nDensity 1.23 g/cm^3', 'quantity' => '1.00', 'unit' => 'kg', 'thumb' => '1655083113.jpg', 'availability' => 'AVAILABLE', 'notes' => NULL, 'created_at' => '2022-06-13 01:18:33', 'updated_at' => '2022-06-13 01:18:33'), + array('id' => '4', 'code' => '', 'title' => 'eSUN ABS+ Black Printer Filament', 'color' => 'Black', 'description' => '1.75mm diameter, 1kg, Black', 'specifications' => 'Printing Temperature 230-270 ℃\nBase Plate Temperature 95-110 ℃\nPrinting Speed 40-100 mm/s\nDensity 1.06 g/cm^3', 'quantity' => '1.00', 'unit' => 'kg', 'thumb' => '1655082906.jpg', 'availability' => 'AVAILABLE', 'notes' => NULL, 'created_at' => '2022-06-13 01:15:06', 'updated_at' => '2022-06-13 01:15:19'), + array('id' => '5', 'code' => '', 'title' => 'eSUN PETG White Printer Filament', 'color' => 'White', 'description' => '1.75mm diameter, 1kg, White', 'specifications' => 'Printing Temperature 250-270 ℃\nBase Plate Temperature 75-90 ℃\nPrinting Speed 40-100 mm/s\nDensity 1.27 g/cm^3', 'quantity' => '1.00', 'unit' => 'kg', 'thumb' => '1655083506.jpg', 'availability' => 'AVAILABLE', 'notes' => NULL, 'created_at' => '2022-06-13 01:25:07', 'updated_at' => '2022-06-13 01:25:07'), + array('id' => '6', 'code' => '', 'title' => 'CCTREE TPU Flexible White Printer Filament', 'color' => 'White', 'description' => '1.75mm diameter, 1kg, White', 'specifications' => 'Printing Temperature 220-240 ℃\nBase Plate Temperature 0-50 ℃\nPrinting Speed 40-100 mm/s\nDensity 0.98 g/cm^3', 'quantity' => '1.00', 'unit' => 'kg', 'thumb' => '1655083736.jpg', 'availability' => 'AVAILABLE', 'notes' => NULL, 'created_at' => '2022-06-13 01:28:56', 'updated_at' => '2022-06-13 01:28:56'), + array('id' => '7', 'code' => '', 'title' => 'Polymaker PolyTerra PLA Sapphire Blue', 'color' => 'Sapphire Blue', 'description' => '1.75mm diameter, 1kg, Black', 'specifications' => 'Printing Temperature 190-230 ℃\nBase Plate Temperature 25-60 ℃\nPrinting Speed 30-70 mm/s\nDensity 1.31 g/cm^3\n\nDatasheet: https://drive.google.com/file/d/1Ipd_VlIfrb0HWdApJCzp25moxtQBFrpT/view', 'quantity' => '1.00', 'unit' => 'kg', 'thumb' => '1655083390.jpg', 'availability' => 'AVAILABLE', 'notes' => NULL, 'created_at' => '2022-06-13 01:22:38', 'updated_at' => '2022-06-13 01:23:10'), + ]; + + /** + * Run the database seeds. + * + * @return void + */ + public function run() + { + foreach ($this->data as $index => $setting) { + $result = DB::table('raw_materials')->insert($setting); + + if (!$result) { + $this->command->info("Insert failed at record $index."); + return; + } + } + + $this->command->info('Inserted ' . count($this->data) . ' records to raw_materials table'); + } +} diff --git a/database/seeders/ReservationsSeeder.php b/database/seeders/ReservationsSeeder.php new file mode 100755 index 00000000..0e3c8b80 --- /dev/null +++ b/database/seeders/ReservationsSeeder.php @@ -0,0 +1,38 @@ + '10', 'user_id' => '1', 'start_date' => '2022-06-17 10:00:00','end_date' => '2022-06-17 11:00:00', 'station_id' => '1', 'E_numbers' => 'E/18/147', 'duration' => '60', 'thumb'=>'', 'thumb_after'=> '', 'status'=> '', 'comments'=>'', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-08-04 15:25:03'), + array('id' => '11', 'user_id' => '2', 'start_date' => '2022-06-18 10:00:00','end_date' => '2022-06-18 11:00:00', 'station_id' => '1', 'E_numbers' =>'E/18/199', 'duration' => '60', 'thumb'=>'', 'thumb_after'=> '', 'status'=> '', 'comments'=>'', 'created_at' => '2022-06-10 15:23:56', 'updated_at' => '2022-06-10 15:25:03'), + + + ]; + /** + * Run the database seeds. + * + * @return void + */ + public function run() + { + // + + foreach ($this->data as $index => $setting) { + $result = DB::table('reservations')->insert($setting); + + if (!$result) { + $this->command->info("Insert failed at record $index."); + return; + } + } + + $this->command->info('Inserted ' . count($this->data) . ' records to reservations table'); + } +} diff --git a/database/seeders/StationsSeeder.php b/database/seeders/StationsSeeder.php new file mode 100755 index 00000000..fe56f4be --- /dev/null +++ b/database/seeders/StationsSeeder.php @@ -0,0 +1,39 @@ + '1', 'stationName' => 'Measuring Station A', 'description' => 'This measuring station can be used to do the measurements with electronic instruments such as Oscilloscopes, Signal Generators, etc... They also can do some prototyping works with breadboards in here', 'thumb' => '1657218108.jpg', 'capacity' => '3', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2022-07-07 18:21:48'), + array('id' => '2', 'stationName' => 'Measuring Station B', 'description' => 'This measuring station can be used to do the measurements with electronic instruments such as Oscilloscopes, Signal Generators, etc... They also can do some prototyping works with breadboards in here', 'thumb' => '1657218135.jpg', 'capacity' => '3', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2022-07-07 18:22:15'), + array('id' => '3', 'stationName' => 'Soldering Station', 'description' => 'Students can use this Soldering Station for doing soldering, desoldering and testing the PCBs.', 'thumb' => '1657218148.jpg', 'capacity' => '3', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2022-07-07 18:22:28'), + array('id' => '4', 'stationName' => 'Assembly Station A', 'description' => 'Students can use this table to keep the materials and do basic assembly works using light tools such as screwdrivers, paper cutters, etc… Those tools will be available as a moveable tools rack', 'thumb' => '1657218403.jpg', 'capacity' => '3', 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2022-07-07 18:26:23'), + array('id' => '5', 'stationName' => 'Assembly Station B', 'description' => 'Students can use this table to keep the materials and do basic assembly works using light tools such as screwdrivers, paper cutters, etc… Those tools will be available as a moveable tools rack', 'thumb' => '1657218403.jpg', 'capacity' => '3', 'created_at' => '2022-07-07 18:26:43', 'updated_at' => '2022-07-07 18:26:43') + ]; + + /** + * Run the database seeds. + * + * @return void + */ + public function run() + { + // + foreach ($this->data as $index => $setting) { + $result = DB::table('stations')->insert($setting); + + if (!$result) { + $this->command->info("Insert failed at record $index."); + return; + } + } + + $this->command->info('Inserted ' . count($this->data) . ' records to Stations table'); + } +} diff --git a/database/seeders/Traits/DisableForeignKeys.php b/database/seeders/Traits/DisableForeignKeys.php old mode 100644 new mode 100755 diff --git a/database/seeders/Traits/TruncateTable.php b/database/seeders/Traits/TruncateTable.php old mode 100644 new mode 100755 diff --git a/package.json b/package.json old mode 100644 new mode 100755 index c648bb40..aeaacc35 --- a/package.json +++ b/package.json @@ -13,10 +13,10 @@ "@coreui/coreui": "^3.0.0", "@coreui/icons": "^1.0.1", "@fortawesome/fontawesome-free": "^5.12.1", - "@popperjs/core": "^2.5.1", + "@popperjs/core": "^2.11.5", "alpinejs": "^2.3.5", "axios": "^0.21.1", - "bootstrap": "^4.5.0", + "bootstrap": "^5.0.2", "cross-env": "^7.0", "jquery": "^3.5.1", "laravel-mix": "^6.0.28", @@ -28,11 +28,24 @@ "sass": "^1.20.1", "sass-loader": "^8.0.0", "sweetalert2": "^9.8.2", - "vue": "^2.5.17", + "vue": "^2.7.14", "vue-loader": "^15.9.5", "vue-template-compiler": "^2.6.10" }, "dependencies": { + "@coreui/coreui": "^3.0.0", + "@coreui/icons": "^1.0.1", + "@fortawesome/fontawesome-free": "^5.12.1", + "@fullcalendar/core": "^5.11.3", + "@fullcalendar/daygrid": "^5.11.3", + "@fullcalendar/interaction": "^5.11.3", + "@fullcalendar/timegrid": "^5.11.3", + "@fullcalendar/vue": "^5.11.2", + "bootstrap-vue": "^2.23.1", + "bootstrap": "5.0.2", + "font-awesome": "^4.7.0", + "mix": "^0.0.1", + "moment": "^2.29.4", "urix": "^0.1.0" } } diff --git a/phpunit.xml b/phpunit.xml old mode 100644 new mode 100755 diff --git a/public/.htaccess b/public/.htaccess old mode 100644 new mode 100755 diff --git a/public/css/app.css b/public/css/app.css old mode 100644 new mode 100755 diff --git a/public/dummy/item_thumbnail.jpg b/public/dummy/item_thumbnail.jpg new file mode 100755 index 0000000000000000000000000000000000000000..9f09b7857af6e461fbd5a5fbb38328036c2be16f GIT binary patch literal 2840 zcmex=E*8A72xWwP-bbMsiRO>nwXPW zQmJ68U}?a`@c%Z0GXoPNBM3nOGb=L)u(7Z(v$C_Xvx6`PCpRYt2NwrBI~Ok(7dH zkx|JhscGpMnOVgprDf$6l~v6xt!?ccon4bAPnkMx`iz;g7A;<~blLJ1D_3pWyk+aQ z?K^hvI&}ER(PPI?oIG{u@|COCuHU$M>*1rvPo6$|{^I4UkDoq&`TFhqkDtFl{$gZc zhIk9^Gc(W@jG>S*VU^ESk Xrh(BkFq#HN)4*sNATbT_|Gxt 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%0AHjaoHy4tYBt!{E+BT8iAKY2dRVwehVUKS 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 diff --git a/public/img/equipment_types/1628189057.jpg b/public/img/equipment_types/1628189057.jpg deleted file mode 100644 index 5fc88c94a04e3fb64ae39f19b77ad68760b9fa3d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47372 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 diff --git a/public/img/equipment_types/1628189116.jpg b/public/img/equipment_types/1628189116.jpg deleted file mode 100644 index 494f1fecb75e8987dd143a129d45db54f3db8aa8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37103 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 diff --git a/public/img/equipment_types/1628189206.png b/public/img/equipment_types/1628189206.png deleted file mode 100644 index e15959537e8c7aaa2a7fd50ab8e7a4c0ddfa3280..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 130415 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 diff --git a/public/img/equipment_types/1628189260.jpg b/public/img/equipment_types/1628189260.jpg deleted file mode 100644 index 0d70d57a86fe0f2be013d87372d10f8e0f05615e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31702 zcmbTdWmFtp6eZeNNYLOe2^uuG(;>JA2yQ`wHSSJ;0KqLlg1bZG?k>UI>24evm&S*0 zX4cGF@7H_p)~!EPw`$csb?ekQ`|SI?_`C^ts~{sU13*GT0(^Vf0MAbV5lMAviLa{a z!nBs=>^6?yEot4kI6l%cySZ4~Thhua$kHl&k(Q-(7y9^tjn>J{#Mau?i&l(Q=p)AS z3P2Kof{grMe`%;M9qlz58Y(Ip20Hqy*H{=>SeO`?nAkY@Z?SRka4<3762HYGAS5Cp z!onpXB_<@rCnO^L?l?)F-G8`{ z04V9u2=XHYUn0T1n;>6UlV?g&#CTy zL&u|jN@VIhg+WZu3t>3>58D4k_Wur8(El%F{|DIr#kCB;LP2_Yc_?@QAmA?LI`lE; z5*+M}HB>9jU;93b1Ahtc8Bn(YF-{1eeEMMIt2l4b*4mt~1Ig#uj`6&C24DmXa7O86 z#k#eorKOcHdg;{i@H>M>;fnG+#G?+RHbpj0+u>@FiLI=INJ%vtjxOr(2^DmknW`!K zE8TfaMQaOZ_n+a4JT%#0CxprU+Xr<-8ojzc!rxGMxN{qd@G_%r5?!Frhvyus<>pu` zFP>JQ^m=qK&%%$&D+-!2J@ERmSadVOy8zmU+DFFs^ozc4r)kg7!`X9N&J1V2{aKS_ zPo;K`y>3^9=sg2!ZjQL}d{OB1=Z~{z+vKC@kAg?*sjg8r9!u{S^)tAq!lUWi<8B;U zb$fmnaadP~kU^acMwirA%8q#ky`S<*tWH4LI**mNRfI$C?|l*t)*~U$0K8uO(TW3N zExH!zWZ>TyqpUWcp^b73EwShAp_*llH&>|kX?gqn<>1g3bA~r97$kUSst31^hr!*o z@@y5^?{Q&qa0M`bwF{%Bp&jh$h!%IgEvv7StZs!&F5;Vx+wkVXA4KAHa4KXgX8E(+ z9zg+b-GZbv_25)v>SJZ**p6JLrTe)2gYq|H&%0^be;3(Cviw6zjjv>{%ygS)^bc%{$MtBmY@Pw6<=>P`7_U+4y`BLP{^Ds?f7pfr@Cn8a zgV_#7BO8KSVk7e!t}eN+$qv~>^PVEtPKb;%e(Aq;15>ufPeyLsX0TbNbzqX|;bjEt z!L@c;wFVS@P!X;)6t^nZl{jpRap5O!r#+Ao70aQ^oLu6CfRaIe@EP~{O)XAyDO zcXLDiuGL5n@4lGlk}_+&ZQ?rUF;dhC%Gz0t0O};{$~OHON@hq{UY-&VIKB?T{6@I7 zE6Ddd&3gzGFT#mH|DjxhknCx+pi)$id4j((qOim&^$GR=aj%{Iz_Soj*HSBi9d@m< z*Pow^{{|(-r8)5M=o8&^7R>_zlTrO?Wr<%o=(K&UJ-t@i(mI)2u2`W`t_yY3q6xgD z*mJROjO|vT@FgO$tRb@`y+e!7S+#LO8%O)}Sfl>ZvWEYa%a9nL_{WfKrVW8pT>}NS zl270dZl~42^#FTnBlDA9#;}avS?3+%$zFF0RD-sTnHKIhAh@tU5!aglGTUd?A4wKr;uzci} z76MMcd+i;A#*{q9(e-f_V_C=KU>0&gd!3Jt)^05c2#)xa6pp)YKs{FkX>~xP=_%~m zunjLX50%&3R>Aei>0|k8&GWas_5+^*$b@dp_X{fBGZpSJq6JT1o2*uxpWde^Md!}I zWhtdPM+%MP$6R>Ia^`(GqgFjjhj9EI1N08X8CJ@2nV{vlgOKFHd*|u# zw|+d&fO)VQ0%U@Z@c0rHBS$mRwhK$jZb10BXPYy0*=q96a786fJ|JdY@7Wy&(A=y= z%XG$%2xfN+JnjU#H&8qq)qbkdE7fpJH7L0(x0ykSYn|+%=vFfFW+7s@e1X5C>mX8`r*2HT+ z4~kk~5ql3j_p%fA39^obAnUIjJsYt>a@2YZrQjJ>>kKAJGrLZj)5ABuUqb z2KDx)=;7o(18jcC*5S3T*GKmP93AU9a-d{xL&NUcEKBql6YEYBe5vkyPVTdHoH$-^ zX*IJkLIVW>F)##tBzC3^{duNH9L(|8VmC7KY`d67rT*%s7Z<^x6;{BeEzY+<-|iGN zf8E)tTIjv7>U_v8lV%4~bfaP=(3sDO_AoH87l-#7rfBd9afV5zpK^9>gc@VeN=>#2 zSTRb(3Jy>WU$KGeS{DkXm+a%02V*xW7qUPB_~pENBY9zT_l0e>{ToyXbCj4NQD(;_ z!@1Yz^Zty8$UbhapKV-? zX9Qy|9?JvK1w8EKGUrBV)dM#3fsibUhfhv8;dv@1W>3{-%Xv?zo|OU-&Ir6cS=4N> zfN8|kEuUd$9W9n^Hcpk5q_m+qssW&-~C~N2%d@e znDp=tBJ?hqRl`NpoQB(8Uc64PLOH5H8&^@fOkCtNs|Wb26JJ*)BVXCh>KSl;;VN2( zvcLp}7;SHME(*_*R*D){jCwxm&5v#y=a@}wN8HVi53^MykWQ%)enTTA`o_U3t=K#) zYOtNJ8AH)cgDy&SdQPZ}DN$D!hhuquqp+bZ1gvm35eu6xSay*aS(0WjcN%WC8HzYl zUgnDU9V3_jKDp<^0p6>sW{t_dUYZbp2Va`g$HA~CY@=0Gf`Qbm@XDfK=OnC1LhB~W z;?;7VBhaOb@w_V>U7@LUj`Lept(3@4Q{4L)F=b!3GZ(08h^W@Gd*bFTxiYK#ug|Z4 z<(tJq#^2ls9%k0(Yt+W)^Cie;mWA0nHtnVwE*{vlBw1|kI`DlQc0>I}{X3?&FTkcY z7GvLciz4wM+P7|S8(a*uS$zidh~$@uQUnDk+^HnP~`xVNd7CV8d_*!ZH@|aDnvsP*7za*O>Ex)mGoUxcISjinzZ&nL1amvoQH5ndCyv&;?lfLBLxS4jIdgQ9rmE1eQ$MGZ8R9tzF| z19!=P-e@ol{kR6>v`)fi9i9Q6ou04)fAE9lW5(qu?i*#NSGSb{CXueR_u8Y&jYo3@ z>`}FP;b!d^dc0bYwCSei$F!RmILq?jkm6=as)ilFA}*t}bH3S7zn8?_17GS$a==l> zoBZxj387ZHzd-GG66VJ2(lczI`3-%8XqWmULZDRI$?2o6JbU6!--zn2o{wCWtK}56 z?B=00U44cHJ*27Py3rt$#m521$Qoa%hLdb}KHrtrm3GdBscMeNPH8?kSX%%4)|T3r z?P4FgtCPMB@?^AcHRVQITThzXse}EIa8rwzNkzxOW+tLO;{!d-phVsZFM;MUt*SGe zyb{GNYhs*ZPh{pBn&~FXKhoAHQ$;Bam6ulnmHBh^q!TL+(&e%V*$X^=#e2fy@Y}XO zKD((WyfjPq1O7ZFjM>kCrK(P*F(F$&5$(#CaOBJBKv<2Pvc6^$WtQl6z)5COM27bo zoAn11#|iC!53z|M8^3(Nzh6SQ$o`#8Mzd zOUN)&)#*_t<3c>p-9bgd!N6}yhd+RlZvw|IbhleOISx#-S6#;Z4Cnyuf4Cf*I!?fA zoQ)Vy>7Dl=TSKPl(l!ga7pBGzaL~Q*(aIV+8|7S%m0d0Iv-2{4e4V+Ja@FrnO@mm2 zOyC>J+JSrsR2~Tg9Y$J2I+6B048%%l5UKgl|g;nTWp;iWnmxDt+9^|vX~WS1ziVE6qHQ&wA)4c=EkZzSqMtiWPJdy8TYl2kFz@ zAMmy{hp$2Z;@o@mxjUz1na;uK{_mfbwCP7d5UP)#`O}S!qZ;SFI0EtglQvUsdUh<@ zW{=JPrtMf;`i*67haVc?l)zT39kf*@;Y{=OWZ`e@tU^W`nWC`bV--4dqzxmr9%qaP z{MpaYW3G_Azy}M$KbuExkqh`c#B(Ns6{?4jq(1-S18*Gumk(p~w=HanMCp@RdM z5*{U^G{Kj;75#nKA4f+7%uK#`lnkhj8BRT>^F9ND^%VLG3|4J`_KD-5k_;WeWdI7m zEG|HJt1P0hfZXojTI9o*-(cSP4B_-;8NjlPvNGv0?&!XDicGU|e;$Khh}571P0^6XR&479(Mne)gP1-D>SR-%kf2!Y^Q84@cZlIm0R_mPAa`iq^Ejr=M^0eR? zqVu9YRn+A@ah~>>Bl)1k_rn;~6Qo;~hl;5y5xg1ly3{(8HPjM>J$YGr`&%Pr37#f{-v54_tu z3JtvTg56|yQ;!)e_)b{`no~)sYeb($>QU-Ndk%`Wfl0JVNOIaFl#LaxG`J?*h)y|U z{iG+iiKy+4q&eS@6m1T9oR6ZMdfy95ZrBumY0zc&i=hkcG261qHBWf^O1#7{qt%Pv zvfaF#FicxYNQhr`{&<$9`lm5p!&8Ab&_&XyD2tAU88FaUsPd1(5VTL`Tvq!!2_69! z%?|RJd%ep(ZauBoZ#U)=Ei(v&-qX+3?N?+aeHR1m_HOEr8mdS*uUlcc*PL=0%h(uy zf-lt1bqQ!|D&noD6`L3p>t(t)ZYTp;5IjF~6{brsiI?d}V`&Fj7?)1qi{nh6ROQ70KOm^sbRrcUuWapO`yNMxy;UJYK`XWlg4b5ROm@LYk3 zru_LlOEDp@iXc8s8g11zEl)|8ge|5m4hipGoYI!BCKQP2sg9na(bDiUb`zBZ_(`bZ zyH~v(j&6^-jao(w%l&oa46h|-v4o4=AOpk}caX?O{xR2=p{(lb?54rX{|wreHP}g2 z?%=y93e5jJIs+E~Weo=mw7F=^+F!}*`TYG_>r6z*O!EoQZ+%3+wt@~P1plkp^HYRw zEbB{72lwYoEf);IyhO~<4`-i}>b}G;*a%vfo0_ zaBMFr=Pi?74OB?$6~{n?o$1tgf<7gWOu-1)w-H?B5h~n2qsUiQ3+?kh5MNP&RA;{7 z8;+5iWvx@o;{jZ%fgvgN1OIU@roo#H?TG+`S^516NwfK2Ms$BMcj ziwt`PYTKdy&lxrRI#@VAZus`5UB1+rpBbDOjyT)t?D%@X*nuw-H`3#vU&C9-Z)2RaspcFjv%Q0j z0?v4P7oGvQzVawm%YFPLxvwi{R0ZC!Nl@BrNm<~M(q58L*@O%Ze)U{dhkaWDVC)(qN! z`*C5$b(o@E-;dsEmn=RwBm5ZC*tc3LR*@MOP5um6FfE}F(`^v-c^+P8pXNl{T|Nrm zYiK-ZBbn0t*jkX>ZO`?ZD}(F{D3qzCfC`@huO`r@{d+x%`lj_W`t0Ivw906fgv}2= zF;E5QU3R|OulALjd*4z&LpM_{Z_P2w`FNgvV>aKK))^%1*Zq&qvd~GlO-eYmxW4(K zeK4eA=y9%VxtESl#`v`gVdD_uFgW#QzXKrez9UGAGHV{M^I{_;x0TQRbneu}k`@)3 z%7(ahOAr@Nz3;GL^chOc54^gjS4VfZhrZ6+zEJ3U6Xbo%8+FjMgew?V)a* zy2nzz)#Tjy5}toX{WEl^e$v`LO5c(+5ZZaeAeMv#-8{4DQstr*IThQbuXo;))tI+Y zhAircTu0!y$Q^7NV}<<=^8Kl9m>sz!h!II___C_(q zP4$#BDZkUgj;yNmU$d4KzP+dKt`YIWFuVlTy;02cTx}`$Sy*{Hth}+Q&pc7n4O>r< zjQyt1x49WRb1uHjCSd7~_agB}sj}C6HH=C<;H{^{IQInFNUee#lTBdP!X9ly> zx6YPT1~gnql)I@D$=FNiMDA~u%XJUyEb>;yG_-kRLKUt1C}HojQ)e6~ob+?7_1^Zz zVXI3v_t><^#WxbcjdagqyU4-6I;auBs?+TMmP5vxbztL|&fMr7JVsX~`tRX(o&4V3 zGbW7$-;TQXr>jbo`CWU;B7pQy?|f0uQi9lz@)vB;64r?2G|YQNrJ9l4X*ue>b3*WmBmVYDy1RNDNQ`dG>8SAdPYE>tq@QeiGzU{W4d< z+oY#oGEF*bo+1eTa25ck$+N~fwT^tuaTHu_V+QIqbq_DSz9wUoOL3{mjVXv>ooLfP zo9NBN_j+r~1@p?^PwF7m<0owoaUCgvO3$WBN5HwfHNL!SX^VZB=HAGLop zo~*qd{;+ZZuJ$FnXGP$49ZZ-Nyx}naQll(FhKaXoSp+czJ+Mz_o>Rmlzj-h6J1~ef zQk;Nlq&l2xM`_<-EdShJkrpc&PCZ@0gyBVgL;5ePS0vHboj%Yl-3GXL!W zf4)=YoZ23s#IB<6ExlQ8)YqmlOVbqxXU2Wyl|=O_Xx_yii}ksnh63Y*)b0 zpxz(TzlG(Us5Z2kC^Ng0=acDlukR~gjmUz=V%yxg23BV;>Z?RP1K4)tP7e{}cN@LJ zSv?})C6sPGhe$rs%`*(^^IKVEWW}Z}oFn2-!YE1i2+AvPVq$NqcG&f;R_Qb?PK^Th z?MfqUW>(1egN}DW?A?F3#wQ~@@HUEwYH|~9e*JESW;Z-wWYSL&dliEGq$G${<~*mU z!b-ZzPeSi-BEbmgpmImDOpyFT2?OO@)wRRLbgX&V@cQArXf2ROt-Kk&j5#VX>XlKt zQ$#hSo#T8$s`kv+3Z|NRdwKJl+ANh%o-j)(4E8v)Z_pI-L85?hBH&#NaV9t6fqK-} zjLM``2dO8Oh4bc{&M;p*%UtUz-Nlu1;ypo4D!+*en^DNRpz(B-IGOJ!an{p}f;;Z| z5hSXA=B|#yPhtTyHt-5jHA}vK#4|lpW2~s^Ss&>aQif8i;iiPAb44(pM_ z+z~6XWhNQcol4v)OBRt-1m@Hi___OZw&K-bbp`q%YFW6#5G}aV17!-fipdPTv#@IdS~`j z3JI&lAlzycUfomH&69;#R8uEGiP#p`3(#%u6cti@o#LEdQ!b1qizCn5f!`;5!24k` zp>P-08&|WWUxxeV{qA|?0TJaC#4JylcR!81A#*u1oF1hth?P$A^g@-rX6zMXBZcoj zr&yaKcGJf$(y~*DYI#a>xZ{px?3h(kT#eT^q)Du=`Ziv#1dFfdvw1mr;dPrrMP|XD z{>J)*a|AsDTs2$ef(mWw|Jhw11;#n)VeH$tMWwsuvKlJ-yi=#GNbEY4wlH2ZP>w6I zx%bE|Xry9OiK+&Bj>?}NVY6?qI)zXMc`w8uI8F5D8#|ui{upi;WOw+9nI1gxN6MY{93}F&gv_z{YA}9+ntJ>|J=-0-lDZ!n7 zV%f9Di(%YrPp4(LN|yyJlM!{wgd(*&G&r8BgT{Ck#z%IHiXvQ$gDtJ21`D)+!oX)Faiq`SbbN={`&0o0GbYq)f;GNDrOwZ6Z9(y>gRs81?a ztkc)sDRvHtHGI6wvg8gKWr12zb=+mG^)(OU{l@tS;lH#F`-ZBa;y_P_z6G@v3C~cE zO**QITk^xowl@Wi62nkVNfz^~7KDU6AzAEZ6owaRq^Vgc4<{6Zj+K%3}dZO>u&P$qc22fex;LRCed z`>c}Vc%-embE*Ls)ldat#Z2#T@sgUE~TaNe+)kqtN_ z>5Ixv*j1W#nvAlue!VRCbnwL2|Fo8c`apN;po;M9z@K_IopY}gWKF_JU!d^Ta52GY z!k-nRDMoIMt`R#-^MJ+U1YzUr0#)|;8sTNfk(V&?osFDPlA>6!>uUc{_X+9j?X<6& zbpZErd4onl&ttu0k3!rhbJ|c!Gg7{*A~@vKodnUDe~_vnY5l6cP}a|jt;qZfW!yB^ zrQn_rQz5AP=!!E$9IZv3MzQrQwCF7goIENQ^UHdfed)j6$LnXnk6G#FvKlYF*p^0- ziDfXX@g)$jf@}A-WOV+#67i}lD>6fxB7EXom{Onm-g#*x^vw)xLbe)LrFp73`O-TZ}Tl~Jk z&_Sn@afxHxc0bkv!+u~mueGULg1~R?Dp9<;)QgkY0L)GZi{?CUJ>FqM*@LLpo)F3- zWbr=UK%mDV5=CX64Sw~P91ry2LV$COteb4G&^u;s*O1BOvR-+2(QUYr5o6u$eFLa1 zw+;lSuW*m8s$|+_arBeM1MzeT^_A_dfzqnZ_>xOe^bMsQ%ek@av8}vv1}Qb{cPC_i z=j12-ZKQ4m@t`Fs$u1O^m0@XA?qwMGki)j`=h)L;vd8kT_vDG1D1|;8%|vhN1ot&` z)|FNXm%1(_RtTunVc$%qUV) zCplAa?Q5Fgh+`eeK#ZIj2du6F*hAzMBeE5B}_Uj&K z=~5L}u$H1DXi}frL7&K+az?zKz9^zXtWWE#b_DX)S+@x}Ufv*)mOQ88@GcHE!0p%{?u@^--?md#dj)p1Lp^$EJ}wb z*!48I#lEhXTpqI(pvX1M*eTFKRhb;}zCdr0UxVG-w{h{!VnX;b?)@swY=sDHN>VB&Mqcbv z+;jFpmr$D(_4{#wSslHC&`Edq#3rcql=EomOc6S3&8Fvh`jp5_v#*!=g*&rJW|Uft z>k8cHOLxi%+3ogW$WonRADhOizuLtAr|L}BaRP}r@fCxXQTcP*G3b60yj1~_ef=Gw zz_nzUiGDhG{pOVBXOuuDz4e1(an3sN(eDNsF(*o^jvDi|pH|E?d5kGuC>B*-4X4wz-sRk=$4GT%Ie0tpp8Wp9md@1Q zMV6Ry6#zK-8DKj>h7cJv#&Qs)O|3DoQCFp`Zm;nwpA$#9M}|mogMhGEK2_=NHMpO=KQ&Jo!F>ljPGJ%2=G%OtIek@BA!DKM zW!5-&H{Di!JoNYdjzS`T zK-}=cj?1`&T*HQLC;D30#}ge*|NR>Ic*rR9QXV*RK#|6Ne)} z%!5S#n}^fht~x7HEBmS5ztyMW+;p$Eg@Lf`ZDS?3diAZK!x0HqN1}54BRd^mA9Hz& zs!|sWXL59QK99Q4n_y@o$&Mki+EMbh*1%`EHCT|n?n8to*G#@z%&xJkaJ-uVhzR`MOYQqO2 zzl(i`o~>lscA=IjlD0$_sN_C0xION5Igy4+`jL)X;lH$UK8S)#G{Ax$H_fN(1|x`Zz8tgS;!B0jJQCFBwGlKS=uBzF8o z={hQD3R{}>wrEie5l}ZY`rOFj+h7`!)->Rv+`BeAW=aEOQ@f*poUD*YbZ9R}oEUP%~&0BPwYb zsN&k%-h~X3F91+xih(W^B_B(l-dlC(^OsR=QfWbngdVC5wPS&H#)OD6shD1+#z?97 zMB4=}{#~;e_buQ04N`e_)%VW99+Bczh@$&Xp862K+Q^mumRYVpN7*9zW+!`MW4@Ya zme(m~z`iB(2K~_Kx=?yd5sLxH(~28VC21>VA%#3-Hbq-w)JZhVMV^(|LVRoXL-2f^ z+=!;PRDwp+uFy?+^b4!AD1Q%Y)Ai2E{pMRuP7dAiA(-3$9 z7^rq~HlKCmVw~fxZ#wW6*ut7zxKl!GUZ-0-NzU@!O!~WNtOPpYrj6J@sGCIdFSP?@ zwITUbJ(#b?nMUtAUW|s9A6crX1?dV~0LE!2h5y`wiz0hNh;3DNKr+-wk@LPytGeie zZMd_d%f6kWVbxUb1t&*tqX8v}twmdKe^$MCSPqFYBgt$&OSd@Uo85vzDSX83zKJ%sIm)*tBZX%Q4X@7Fezp61#jv+9ia&j)8?ek-&@+^8v}-rL^N zba%e)c<1{qlPAwQy2v^KDQy%S&vk&qbBl4O3Yj>ffQ*sLIr!=qPe3WQ-$f}52nJpX z-v04Z_T$Xmcd||{A>=AoEAEme1!#rC&dZzAr<*+#<^GCOo@PdF!o}F??D$ud>m>rI z+Dy=4G4=W1WdyMVE3J>}4fWOkkUfprh5tm`ewE zJBJR>O*hd_7KS*@*y%Gsr~QMAXmagKdY4o~c(VdGDgxVFFVla&qWD!&@!NcuCxiy9 zcMhcRb)C8Nq`JJ6%li^AeWEh;!VIevo%LIfx|LA9Oq-2g>_;ZnMM>{MUg>Uq%l2n% z>l_TIyAFYXbg}>F532QD08?-wYn@23-nW=gZ8(#7nd81SeM{74x-#&t{u$tgj&i#Y z0$N@#fKntk&w|b45;K~MoujmNr9OyqP*mA)}iYc`$3?$Bt)!udAu zLaR#;aVDIc?ab^|D0Ur6%2}gLDUccn4cEj}VLBcy+x;_UPAFn%CLfyZa%PK*55^18 zYwH~19Q==06F^22`c_>_=Mhj>Mb@-oZWN-c%4K#e>uYQuA71x{U)<9pD_{K?n+wDZ zIZHM$1hhe)7JR=>TGw#V`gVG^TV6|@iKftC*B49--Sv$<1LAVQiK1>WQnxSHcebtY zgSRay`FdQP4=gNlcMrH5WR=#0t4d&TF^U61^Hbv z#yY!-A;W({Vo2~W@6nS8D7jFGay|Er0-@3d_T7q&>xqXF`w~?HQ9!lSP#ugMlaUzQ zdOdVL_G$@cd=~;=@TJ(ky`-U9EKzquO4gM_ZwVQV-W4`UkGXZVB0&i^tw`KAfDgun zviflOZYnwrHwe<% zG|}uD!6Aq~YKm!|IJz1c^rs~lO@*1~O0Sv5r2X~aec$K9*aBDLZ@rL1iS$5gN^@Lw zl4k%|tKeUJYDiJ`Xk4i&UDjIhBg^`m)AeFN*Ycm;#0!ivPZyTEThKEgJEEz7q315p zD1U(K8GxcUOji?t)sFREHKF+c?KA1|z6N)E_hn%}S^OyyQx#a&rH7t=2>sIsLaJWA z9FLs!#TB;muD!7Ic-?gqrUGPoUp!rHx|?+G`AC}N+5(65h!Kl;G09Cz<1+(2AFQYP zoAvZfy*}U)(W&LpUD|^+(o48v?5-#DR_f*0?wmvVUQmlgzO$NUUgCO02nWn6=S5To z{B%0$38&mxwG%vVHn<~LZo?huth4;(t3g@aD>!5K*ZmLFA?+|dh_#o)SJSOx<2CQS zE@x#r%=|-B;^hEnS`_b|+w)=&$~60FicM#iGw~hG@j{8s*T&V03L#K+?;-WaD8=11 zL$TRoN8NE~06w-oLcizfBO>Tb7V?PmHE_Xf)d0ErQ35#KQHF54r}Gr)_SfuR>%4A1 z-~4M|)eBS!J_p-Y&9J);C9~?_zn=ZZ!h!akP10N1O7ExHj&Io}a4~4Z*TbK4j>YZeF7LKUU=C5fg8ij^h%_sUOd!U9P9&c4Z1<`~DllzEWYM#(_(I(#X z&-=P#t_7k=3tC$z$qSvkjmWxoB-Lem!r^85+dof4TbcZbt82NnZ}GNfdmlX%0C}}ffnHy=^p+I*7;jLk z2rz7ZKDlP~H>hcoqOjTjy=oaX>qtpV!5e3=w_$QoZCIC9C78(S#+$P})0#TVt>mMQ zDLp~-V1b)IF+#H#bQ9kT0x_)amJYnpykTs8neYKURF!4HWl}c^3Iz?KO&13)!w+0W zOPix*Ym9t#`uZ9+s@N9DPvVz(!u1;+wfPnmdFl^F6yUy|P=3vo5Z7j-aE97v00+Ebf@iwZ^yIC44&QiQp0zhfg=fnsgEJ7)pJ}N%-}cYW%=@9{^y4;x;^p?8|Hk2=1GWyRuzQVO8+g2|3!}- zsO`~I$<-FFzRa52U=g=%*wI-jdJq0M;8(^!bbH-f%ZbjHoA5?M?0%tQ_O@6gm)l7r zF28VoXyw9(I^b^Z4P`12qvi^kN7V?8*R61#C2s6B<5G@;IGY#P}8Vmz9EqWXYY8Uzo%M!DLU~gD3scE z%I_y|F#l$DpUFziOavPbhe(8b2f~fnhRWJI>aTYDp9@AlK&}|24n(+=uBb1)Hr-S7&m6jWk zo$jh;Y$u6wMDt;f^U6efpG0zv(ki zoddOEuc_ip?`_(|9ca7gr+Mp}JpuP97(D5AAq zG8=>rG}%D&&|GHn0-X{6KqZyCY+ey`lOBBI2k}b(G$q&%KqYg0Y38yzKcYzz>8O<@ zb3BcW&VF!PlbfX(-7I_>e0@hS>Q8iW4oB&;d)l=o}&X~ z_@y8QRm1S0zb>|S718%&@v4AI|8l%pkTsV_WOhmzb%;}0-%*qu5)79a#<+7I1*+EE zJb)q*$2<4k_}z9$CNy_Vrm9#F;(pL0+=H)qx(+sOK_h}&;N4Ji&uVk`#Rcp0u~?^XrUckO6hD;Ac{)0llOUoW zMpW8pKPuIZKe>E1cyzd_O5!PeG4O;t2b=c&^KZgNe~TU~KBgEn=t}}K43Lgq?^TP3 zgdylflCvrwMCUI@EvBY-4&0oTex00yi;&w%AmAS2#%W|l3K6bRCw(LCshDKscBxb? z5!{yoGX=xhM(|YzYo8H`z=bd=^zW-LL0m&(Lc0-rotB(PlBZ91pgmL9mh^`~vD)bt zAhIVuJMp|6R65pkH{z0tq_@nL1b;JD;>(H+mmzL$PDoLRy7StNHpLka1m-JObN@Xw z&jqr9-;WoAZQ4H~Uw2WXWae$zXoGNpYR7g6J`kND&0MuRL#>+eRC)162@f-KBDS&y z`R;hW|AI)N3m&L?cO!x~;RJ(5RL#>@YvSym=S_aZbaK;Zib>oMMe8Z}->9io=5WZ= ziN8M0f(Jq=6w}n8cH#?aGddv&(0L$-u`eZjq5;hZz0V1O_#+=GM^_Ujw*a+Bb2Y2LOY8MTEZc`p}hOWWs zqUOKmEeyrqu&YedhdG&0{uRQ^{6tsiEQ8C}i^03iM_fL>YN+~Mew_RX==JY_Yw&wX zTU-foZ8Zz&R>@^ao`}E6NM?OfPTfM8SlxYoSkRlTl50LkGS`ym_DR;*mOiuh?J0|h zjCxM2k3%~_Tq@Gq2Ej288V_J6jaojHE!wx%BcHY&K@Q53wpXu1;d&JMFC_-HqR(Y7 z3<_54wtO+-^Ys)NjLT3481n`NBZYoR%g)M$q!vJ0y<1Wl3+eGoWqpxb%q4~}b>8k? zR2mtIgAO59NYRp}vSRIJozzsB?BXI;i)=Pr^FIh!qZGm|4)s#ImU2e{15Bgwc3S<3#7D`?F7~+}!Epcajj} zqZ%HfgWnOYjJ$3p< z=TCcInDs&PzWQTkuY$qQ$k-n1I5;|*udGJQMv#fIIjW$heQpa|gwis1KEgUVRqr_U zQ@L>Q);x9n88W75uR}=OLuvf^K;r}6spVh*!P0mBjYVPo&9v4{kE*M$hqutSH!zT? zF$cB4#h%aXX;mJzcWkoQKR^8e{%Z^^A~_lHGa)lQBRqsQ%s70y{94#$aer)h*6ppC zQb0|+UPl_j>7E+_>;hA*{bL8)lnu9b_5uQyRD#+Szod$Q)bniR@&HIb(Ckz{xannb z`>rcWIcbi4n7(nWZau!fZwwGP7q^)de}ypX7I?j!)IJzq?{?d`RygVgJQ|#Q5~|!; z(fdnaxtJHj3o$cbR)YtsdG6{ZKzD5g6hfSV?rj$aNuA4dqZHvP$2D>r)9qHD327J@ z%+0X)>ByT8NAE88+`X^C*@wag$v5QQWYtkg=;(_JnfjiJis5OGWc0hVBZ5TE`Uv)M z5+2}9T7g18HAS3{c^DrS$OkhBkh{#y zi2ju?Li0D0%GYEjbibAK&hDJFaXNSe(AO~2Hh62zr&yu|p+y5|6kL1<;wULG#zd%p zrU=WYxi>Nw1?o9YMB(*2KUvHjv&;%eYxcEzDD&~;6hts zLY*5rKD(+AI`+EAPLV9BpPi?6M~RQPy@7cgRX{evjcsOKLt;NKd>?j?20A$gtf)=C ztgHpDLKTQq~6%z1?PQndu`ku&`!BFHAn@?ps-Sl zeX|KpjwS7mP>P^<_7(c7_9!*eG#|eRWt{{dr+8_3`KJi@-7jR=W>kTYh zzDIF+oQM|v{AjX}h`PVjO+%M-iQN^PZ>)1s+o%8b)qIx6c!kp=N9jRHbFrYa@Uy@y zekwuRa)3Oud>L!l4)x7;63$996W;+4$1Q38DB_>O?YFmsmAEzs{*3-(joNpCty4LQ zzi4(o*8cSTbA=*`r{9UwfwtypKb1fG)8CBf86X?dy(~6n=Tjzan1~7!Y0ODt;e*7g z%-BZv_mBRXWZ6#3Y&tQPec*ij!^!!LyeK?a?~QxBbyoUC*UAc5Bdfs9fBXrhmRg{F z&b&rSS$GETAy3>a0e$Nw%T%}{wv(ArX}tfwTH=6FrT)(oH66Ezu{!lPTLEX&W%2oJ zYZSZX>=3zlAOy+sdnAa}8YLL7=k_)_aN?$k?y?ep7s3?e=IJq7*h9Iy8-)YByNbWp z(?3wn*}qwK<{8BF^1yCFlUqUesB|tBJWNzZ$QFSb$Wg|?hQquyaaB@deNH&(?h|^j z9j6TF^`4K8C~GC0d4Ddc9(O6FCpDs0Z?(OaI(>n)$XA@uX5HX+jWD#4*`l5RVV!Ps^>q^D-lBS^0 z$GGTh*!_J!GQLtfc_G&VpOxMDwtm&-^db@6(S&r^S&t0X=nuaJyfe(3Zi=Pwl@lkO zW4HVHKLU0-iN$-CX9>7;A6n<*@pO>mgZLWE)?ZHXD($@v2bid+tuBD&aZgsK>?QJV3858Ov@6cH`#lE(=fM5L3CO7&eQ#uk1`tcL^) zS4=C>pV~aC*=8<>#Ru{>8%stUiYhsLO=BcPtb?T$)BC>Y^SzyK<$rTLOT_*&n(f{1 z?@WWJjZOfr0{g~OJ2Kiwf$NISYet=nw^D!KMyP5&Ak(y%$OT=8!v=aj40@=0ZX2P5`K`Z>%(QEbOeq(zqRC;#9XX7%g)n9s;Fy-wZwz*m(8U=f&PE zk3+R%#hfE_%strfzpZ(G)~$JRL-9U?>M+7m_PB@2zcZcHJ|LHrTiHhQO#CcRf=NGx zb)F3Up8Rj|8dSN|H|P5BOK6 z&EXv?Sc^k(iBJ|D$dI~C^ zy9J@<`zrX!drIj*L{i83J`iPn<>vcR?fyX^Pl_gSvOY_&iQsEdUh3dVUlX8jB~i~ zYX`1}($b7+>XxN3f)A|&=3k{efUJEeRlpiTdWp8Vl&OiF0N5jGLJtHCckf=` ztb9Mex{aVqm?yNA86=HKfw03F1xHbw;PJ(Bx~G9WMRDRi6x_25OFxxvqmRvFh6m^5 z;~;hV^skJKJmUjDXw;Hdz1K3^%KdsCWkol2DBk9$g?t+J9vZi{yu2EP)I$?oG32&+ z8SX}Lnw|6;c`v@mx%)tm&MS~c%%TOIaCsDbcb)8E#V^+5EU@@g8$VO{sG&ZFt+#`!#)jjVUki3EpFbAz{_?KL|)cilE>G0dWp{o?Pm96aL^42g)xh>BM z23Hx$&pj*j+!ke58HI%EFMX|TvA!D#53>4}zAj$3j&7RQO4lTfEW|PSD%grszYGrt zapiD6wbm{F0G9%;;xGW_yx+sV1-R062{nCA=r!Z1A7!@yLY(I(0A;h^kH)%Deddw# zS9_aVv+Z*12PHQtD_rQ|)ca>OWL^i!u4X&52d^Tn$8))I4r-Ln>ClfueJ=n6RC3%L zbJDY5xdZQ1t2XdK=}(^M=k``?vg9zx>r70B^r!^bCkCWRa>BB08pbUx4c#vapw`k& zfG~0Nu6EArXaM6CqPJizV<{Zch1se0*IZ%Pel%7=y3cwmKWQb@UssFWA3Dk6jc>)* zX4guzn&sHwEJ{!7U51zYI%~J~O?~1Ezp|#?!rC*IKE&74J{ItPi{UFZhfcDJ4WsV` z8T{%G65cPA%2;z>RU9Nzy+?EM+PT|byTL-7U($jT`uZWUa3$}aJ!f}tAJ-3v5C|{P#&wuOG?V9r542V~A z_jamt-Whpj$@i@1n5YMut0mC~lUlj5A%=?Bza+qSs?xA!CpAT{GH?$S1lOko6H?`K zt~6REotOA|=Bvs#p~(RLbsF6a5!aseA~Ka3Jer-(i*gVczERv%Z5|FlIQ6Sq!-H5Tn6fXm76-Pb*X9YKwRz>nQ?Qu&p95H z=@bH2b}FQ+gZF{_YY97@G-DL*JI(n|G>bUeIUv&t;AXVEEut@owcA?;kiwFZS-{Bv z0#6@>bJUur7b!a>sn+KRMak@n@yom%cBvzsi311eiuU~{!y0yj50z_fgCi{?jn4k$ z)xmEVa71W7;5GQxH^j^~7ZEx!!%6bHYSdrdugLNqIx^NV)70_}A4JqOJE)ayrC1q; z>6r*s9nMX6@%S3XID>AQL+Z_sk*NKJVtmcApSgGI5 z-}AY=Ce&_oC&C|Y0VY0j9tyew59dvPf?gK6x0p+$K!#P?%?kNvu6Wyy_1|0Dg<-{8 zk#@yg*v=`<@rgpNB28b(en}WgPH$7gum1pN9RSRwFZC#`!TIgH)n#Se8*WPE41jv} zu9hDPXu5Tu*zN4n)j$DdPrZ;Z3lqz6>s_VqCl$}#{{XJ8j3$4YQ=BHN%iY^uK5MVe z=T#bNI;|PQYCZziq*wbRTU-OsZz{+0CfrOa)fz43U zH$C)r*D`&PNy9vY?*0|-lis?_NId4VJ}7929Iwe6jNKC)|vC``45;#m$7Dy+?(?=-{dSYTciUuQca#4DNzXp$a5BdYF#i&Z)MQI%=}mtE7^lz#)bW zbI|-j)L9(`%OGwEMG8;jSM(njCXghRZQ_>fjHHremG`WrQjDy&?r5;M+I-S&Jv3f@ z+tW`ZbW-T|_6z&#XIu=DITc)9WMG=blf{>}^2sE(5;1s;QYJj-k{_!_p^XrQ2bY#vrz%_L4*~5-$L8EP>Ax}BQ zP?Lgq=y|P1P!r$1QkelBmD$kwnAp#J=R1EIr*pgSVB^}fCsC8lQk^$P#y>n(Z0mx# zl_an8CmX%$<(ZL`?!sYsIn75jLvY-7p1jny_c5R(l|SubqAy)dsz&kA7GQVAOA-%E zEm;y4#tlUs#8N3cn?Br7k|cbb5>Gfa(R6u|i+iGVkOP8w^r)Imxv0#`zdU2m^`tDD zbLxF)GjV7~kPLB??^NWJD;l12gU1z8MI`5g?rAfkoa{w3yNMZGepOhK&5Y+1NriSf zAB{ruvXI8#wKayJ9>)1hNJru;^G-a) zVsM#Scv`LwPnFpxbkn-j;l@g%sS0t~r+>rz%}i!y&U#{$46wy!cz;y>)s9m9NTWII zMQSI^K^+Z$D`T+LX(-mIE^c*u-?onHb@?0$$+&G|S061&66I_OYE2YGrjcwgF;%g4!fs^sCUV-RRCV=A@tpz2Q@T~X-aatjE#%P}4-llYebia*U z`(s5f%5jf+s77b}X%EkFj>Pw^Y;MxFr$=LNHm(#sn%zWt`KSt!_}2~N?}s`Dm##+g zS=!m@^P!eU6BKC9c?t(y_QiU}i*>#Li5|$*U}L3x&HGdMlk9#sw}?!@!D5GMl6fr0 zr{!O>a7ACMVizQwqa^N|(?!ugKllR5XxGPMzOPDLnmw=Ot+v19Wa&N_wbr~xac5&J z?Pa)# zxgdMiFr5T^a!)`wtzQer2BE3KlV8VVh@0v zy$5hBHjdhIS|bpVJfshljsYi%r8)Az;Z%-t4s%x>1SUob3t;n(YNX22Z7Nkk9E0Au zS?WUf(_!(>F&YvWo=^V(UWhI?J9Dv6^z`?tujUrZDahb)P{%7o?Vba47@su)tGNX2B&v*xLIqoXFw@dR9cpkNx zHRkM^r9I&xfag8EDLI-$4ronuuanar^-^oFog0jFtj4+9_qg`OW?pIyyz`H2)(&0H z+IUwdWNkj67ruRJl(*oMgNCdrFN<St*!aH zo_z6=leATgRq*zoZiT#~D}kK3qQ^$Qu-H<36?a zr~I`)TKFg9zlQI8N%7Cbw+W`)UqF&1N>UbZHlQ332(Q24n7L!8CDA^fX!~9cjTeuc zt2-qZ*4Nc7?u~y2T~xuFTI_52_F z6n>9{oN42+SatB;Gm34yDJwnOe-vBasikKl-oKPxk-*N}@%f6=v`d)dMPJ>V@~(Fr zeREu`tdhle97Avc7$!COSbG}Zg6`t#0AO9cRmcFiK7bnIv+8%&R?%9TFD6!#$U>?BD1K-BMK=Ec!?ETU+vZLD35){P!}q=sd#j44BfNO;L_x_y_G_`Dj+KxN=p4f?eweBB(MOo zGMC4pJ-T%LYp0h>3p0j=M;JS@GtE`Iwo=4=sxiRF_*DBYU5y?$+O=~KhEsq>Gt?Td zI*>;TjPeNUTJqZNm4Hxvg;bIt3ve($9Mrg)MylM$otX&Z1G%a*O@qqx>sq%7^Y7uzH1maWeboO1--FZv#>%2cykwKddZ}>WHtgUJYL;n>^UmYc_Nq-GW7m&r#mlkiLXUBhOk-j|1K+J6 z)G#rDnq#3Xf5M^i&piGWJnYxlMq8q1xl$WA4^?NoRa2G((`1aP^!BQ<#&QozeC!q) zC0o1V2g*k^mvcKz{=Vj~+(L24>E5YJ0X&cAP~FbBMMq*Ilg9(`p<~>{a!H_}9fotw zJwg8fCY^@n$zqHns2xvEE9!3@9hVls@_x-8fA5<4W;2PSETw=WiuzZ^y2Lt*T3o=u z#U;FCFLn8P8vNIfQh8(*{@VPR^7)g0Sfu(|U!fm|8+f||AL`FvsHBYk_tToI;W@*# z*Cc-I{{S&o)w3^bX1|~D5wc&`R&b~9Na$UP*@M%8T-Eg3XcFQ(zhR0gzEYHd-l(UmEt}CarW3*SBiAMEampW|}^8Wzt)ti6~yM0Ae z(LVEkx@z=;FgM{{bl~TQg7Tl{c~bbn`lS|2RPvu@V7Mq?ri$>CRry@g*$GKC67d_@~yTzN}-G-(-f z6+mJD1Msi3JVmd=;oC2@O&pS`aDijSbNKx$;SU~N4Ohmx)!OFWZZ9R5%5F#niLcQ( zVmz~{H1%usKJ$erbJnXmk-TiI{O|KE_zzZZ4*07_zY>O6E>cD-$IH8s&*MkMy)5Wo z5;faM_jzq{(ng9nDBn2e{smmO+rX7WN~%=wcH+GQUr(8wbiA02+W zTUy2pZj4pAjd*kUX1J+5LN0R^!9->_#4g7^_#=vC?y)6_%S=RToq{yl;QAiqd)5jq zpGzzx>a?f1=n`tsOg56?ffz08*RM(|%;)huj{->Uv5}9JB-~r-KME=PHZ_&c(EVdu z7C;Ir4EhXG6Dmqrf^fJbjMV#EU>xJn()sQb<+;Uvl7ALACQ^JHH_M%2!%2lGr+~X~y1weSQA56q>f=w?>RcVvNV;rVHcSJPx(b zE?3a>=*p~Gd;b7h9F6s?w)k0)qY;oFxU4JgPaF~H&2+cY$uveH11WOZDhnT}>sWVo zz?^p-jc`=*KA#NRSCPwV3i)hjKb>Sx3l<&t?Oj#nrgQQE#x|PFdmo#X{433zUgy+N zsFJaQ(EQEcy+UCm5=UCzdonm6W9!XVYg{Sg@vN+OMoE~@Y(kGw*o;&XLx#?A+O{6w zo<&6^xd)yBsj;szMm+FjDd(mQ)+AyVv9PodoC9Z>e zsEHcd(rblJykkPx`r^7BE;}f-6n#QDXSW=biMEn^eif~)U0P~!Mv1E%D>%=|Xtu=y z`+%h6`;(g55K>oc=BdZ({T6-H= zr@6-*!8a(*Hfzl-K5uv1UtWg^ZEfby3V;b`7|nH_JZqa9@7zx$IZ$%0M{1h)LepZ^ zt(Q%9nN>qfOJx=F$WlNoJ@Hfc>Mu6rFi=PU1D|UA`-`HL2wz(>dNQYqsU0+F?pydT zsOs0Z`h+t&+*+hN-P{ezdH_9h{VTmj{rBA}ee27-8)tfu-%D!JBCL6oM#KzfxfLa+ zj`e*W<nug9|-z2YMZk&iBq(d*Mg%*0^itIyb3tu*R;eCKV4U*WDM z@^R<4HO%T?8E;Ld*z}PfVp>vo$I`hG@l?IT3!68IeNne#`BxQOvZUN)OIs~YDikZi z{LyEt*h`sL>s@W5;0|lcJQ?DfO@4i_%%#_zhlU@8dPTg!RAl15XB&r|IdaKtDzaNM zuh5$X`OnK*Z~mnF)-Hn}A&z>jXk6bxZ2>aN982pXg%#@Ia5bt>r)d8GH{y8pC-1VR ztif%~bN20-hCON8$BXoaMv6T`*`)^?R#iXNv-Hd8?yeJKhRN(}$Hn1lLbHoo*zKV0 zO}2Wqp#92!x+uCJ3Wh7lV7F5wii!s%hyYhD<6j-w>3UqhV!XGW{E#D!TYov~K<$jz z>o~e9IDg(Wv|U$Y#-Rz-tIGv@zd!Oi8<~KOhgyD{D*W93b@Se(;%^aZPF_t;WMA$= zb}!^A=7p~7Q4${hX%ifWkpBQY=Dds@Y&0%d=aS+*n{G(-?;G9Q>RN1;mdv+T zQOFx)ZV6L^)MmaF@pO)!E7TR{2;OUkETvgUBx8}*zNv=d#4LsF9yei@cx5^Km>=g~ zGI-NX&@X&RcHi)jJ*0wC3|IDTvyyteWsm+lUv0y)rCPN8i(4(9o9NPa`Ja8mRKBR^ zPIqh4{{WTr`5Yz9{mQ;tPck*n&9fwo^vJJWzG*y3`#oA*7g=V}H6pErC-*Y0;nV%0 zUVlHsJG=G=OuN&yWq-Psm+>nfeUcSp^xIyC@Q=ef&7Xq&d*R(rPrb4;>4x$HG%Tvm z3vT&I9+|Jx=+c#?7Pn9Q{{TblGi**7(WPFT*EK1^R@vFUS!nF`mbz@2<5Nn3g}7ym z{ou~!NaH+{+wtpM{;I{VN-W-fda^MfpFn*o#PdNV-OrsXzJBWSjN|!=&3)3yTa1B@ za5@U-h10t}_YFxyR>m_QD{fQ_@BruQMFjy|?gaXGqPA`HJqX2E{gYdc03aVgDY8gh zdke|f+h5#R8rKFA+}<9AKC$sbyiZga;J zz*#{7v5|v{OwlH~m2NF$gm4M>UPV!wM{EPgUO64TD_`xBC>-?ksy7oE80T+2fE5hd z4Zn#Q)85Fea(4sJAG$vZr8CK zob)3V+O6rcw=qWqYNT_wA&=vn{uK$Gd5*{qJ>=K=a)T)&{cUnBL(F1EsfxGLNLw<82amUv+hjpjR z0|b=_VffY(r6}%>`dG?!J_)9C&1HepueCufkOsGBfwC|U1Gj3bZOH@?S@PKF_RW}5 zT5Tn`098k~WC>Mk~ZX#(~c@OKyb|2KD9j7DaP*XpGJTSg>9e^Mlg7-ZB9FBH3X9GH<}PRNX`lT zdscRuL~?*frVUxu9J_HQ-q^=A@p&xg^~UamSIb8*lxW3Qf|Z-~v*@(b!)r=0-rBU6D)Ld^&h7rEr-Z{)i}sRwE9rLm zzwj*=$$lCU>3UadISQk1zPQ9T=tt@3(V{q61w zo*q<`UE=rGf11|l>2zHcjIp+*sGV5n3uGJ3^AEW^0rcjt={^zCPO0`ej4~{O7i~NmZITP=*K7y=#fb(!xd*s^QnW zEmOPE@4dBZ_SW4}dz>-D%6!wMQrBH9w%cxr@748o(3yNGFCQI5c4CLw`HuQkBdr4TTPYz?@sU0 zSj4{3Z>+6eSBEhL=0srY`GRZWuZlbEJWqbhGYKS-xKtrX&qJQ4>0e}A%oYg&a-#<| z^0&ow`!=t2aU^DRY=ljKDCem?YfcrZNn>QGMWokPe!c9E(Kv0+722M+^8Wxo^E~?B zS7_jkT0#mg&`@K)xAU!?3&xtohuY(VRlJTlVrce7D-GEn=Z|{l$JnO|If3!ZfJ&ci zQ~`EmAnti1j92XOmsEa{EIlgGag;vvOl}`^j?R3-PI1uZuQeONAbcIU>z%@%Y-4Ex zx^4$O@C7|BNr|M`!BpUoIM1=IQ#;b-enfGJSnL@&=Wo3gYB3y1C&y;KnDXkq-`6$nNC}0!TAn8l~Lnx2^j!-Rp4zs}8kY?$DjC2#gL8cRuwE zCUizpw#HxDrnUoQgaCH|?@xGj_olAWG0L-l?hTjgxbc`q7E((vp|cg^xLr7P(pB50mG#{9QAKZm6P?$Tfp?c-GYs}c+o?pmjjbY`DflvTMt;}+un#hy>} zFcF3VvVa%d5y{0e-86lL3_vOYx_J&+zuj7!Sz9foV25m(<$>UTjbTWvr;e4Bn~T>| zqLnz+h2q?PWo=vRC*`w>RZ-RCVV}yXL*c92`&PI_Q5H_tcE;>>QPi4s%uTt6Y|^&5 zeGCf{O@SKiQ-PEo#<{N-E6DZKYDNiBdij`ozKwIGI2Ta55;tSh>sgF;5V#zUgPQDY z{7w;88`u`&*+xh_mVV50*Xdc_BGxRgU?SU3NJu#{g#oeX0Iq7Wrju%4Bff=N?n)IY z{L@x2tzA|5$On;DFC|8Co;&2#oes*{^!c}!OKWV0X+Sqf$Ju|aZC`jYYnfH_S7?=RsR4pz2a!mtI1K@&!^w9g$_z#aJUqW2J$jLTD^7Q?Nd!v z^DT)FkgUHjKb2PdJKOCN?oxlexUY-E;A%qglp6UR)auikQiPMgnOgESG2jAEwPD;u zLt(iUzj(}pZqg1joOKn1{K!cdT=SavoMs)OfSAg4gDsa-Kaa*rAzMrA1QF#yX_Zc5k)+09%ysbmz@IQ+wI9bbBV9saxvSUVFW{ zx`ge5&Q{qBW7K+|tz}&3Qs3W6bE(}!3LlxANUTWoRTazIIY`$hwrM84@_BQ#cEx)5 zoZcAPa9EmL&1<_!zVbyKoxe11I7^;<8}zee5u#UV6)Jg9?)1gevySpkld{h@Kq}{te(XCtScj#8t z^qbi9`^%+NHn0L3cVMXB?vvE}SI(X_vHsD$3vV=%T()rn4cq;(iuxDCpAoMv6u`>^ zS@DZw5M)vGtn0rJ=r(R5(FKN&a3Ln^Rd|ZN4^aYh^H&4SwXIu2$t!?Rl#^*mDh1{d;%z%FZ!2M}%GjTNeF?~5$9(gGNK!ez?+1r&Qp8BVO5{vuy9^qCx!nza$&bJnP- zHDL}wuhLULi=?zKhaggi%~w~>4NRw+tDNpHsP=D=4CmX@nvdnacJAY)8TpU3BOGRe zZP067C=Ha!&qGzNysMHq3f!m%HXL@ypWRmt2z=y|DjHjFAQQz4$_?j!SV{{VQ7XnkeL8{-)61z3|?A?I)kZ%mowjAAeP<82jis?N5@Q5sg(DdJYd2Do7YE9W4_5yG3X<+b zVm2T}0|V66HanLX=~+r$4*GPtT6&b+e4q+}maVbp+M$pP9xDcS$5Nc@k?Lzc;V?1> zHK{Ku4lz_NSA&8pDQtIAcF@JV=O-Up%(#_zWDaXa@jhnHHJ5U~ykG9-xTbs5Vwy81 zxGgi}Z5_a>w=7B(!5{5<)}72t87FT}wN_vy2O|qy6V)EgHyt!G(d0}V;Cj}Uo335i z7ZBV@8E?IV*XvcMi~^fLs* zjCv8$uf^i%C%9905}2V=_00e@RR5Gmc$Sg8ju;AII}Li98j11<%>zXryDzU_Lhv#0rZ4 z08N`qonn}$n~bunXK&W2T6m)R5LP>)0A0E2K=i6Y?fl}>Ig@uLzIz#k!O9%8pwoVO zBdUyXeBZs2X?beRxb8M7$4akpa7h>$&%a9OEPO|#6op>b%T!;T0tViGw311nUtjrg zp@uj4+Ctkxk3cKVpAS;1lZ{xm%vLT?ljfx*Z<)!??a!?i?%ra9{{VegO*ew0dA!Se zt?^289tL>zC$(bg`czs(q7inJ%s%iz!u~bqVmNNC2)W5wFEg@^I*n$b2X@Pl-i40` zEuJ{2u5R)Mc>=P-&9#~|zz1$X<21*efccx|=tV>_-mM#QE^P}J7mBD#_oySdCNdu^ zefw28rbKm8eq+-EH44a!sw3mfd!cS{{YgtnP8QYV&upP$Ya~u zx9%n^=L|E@gIRYiiCsD;sIPkuPuc8xbQ6l@v4eSR8sBrOo_Zc|YO~l(5nU26l2c>#(c0IUCNm&#Y+Gg3a%NXU09{$w!w`n6~BNBo5 z8oE<>QUK>4g(TuZw8pCW`AK8awNkmiGi@1h+PravFXc*k`FRvpi=c_rj2!-Aigz{V zmiGLQzhl$eCqFNsH1lO5BR2#Nwe$Ul?L8%f2(_CVtv*B5r-beQ0KSGrcOD%0{{Z3L zUN;8rDN7IFaBKCqNv?5SD$fd>bJ zQuH^A>{6KS1XXs(8P00VtHoB6g{<2;qqc=ql)E`cYc|oOZ)}F{41S0iStMVs zg>V7Rd)7RbGI(8X&X(6&o&Z)kWJNudu~pvb%)su>eQORY!5ABxE$vO7_{f`kQj|H6 zCj(Diq_Yl~RzWG%We*ypZId5m}7SILvN z-li9Bqad6b^eN(MMJPKoyQFZ>Ca29Q#_7JPzxZR&uC%QeP-vsIxkx5onrU}@fqk>y zq1OCAq}XW*c`fL*W<%sFa%S{C)xfpEV8A!lqPx^CE+9yyk)%k+%B{#1zqh3&E^12b z(w4`s$>1FG?NZuDvNs-5#t&uwwdr0t@m`;(X>jS@f>J~HsBd_gpko=ZkeCY$jW#-10QAI-doCjn02 zE2rAjlD3TSCxXP`o#hsf)m;>zLTlO0$m}H^yaiy z^4e3iS!QxR_G|MCLH(<3#HqV{N2gvZ)Vw$QRocY}MZOB{-Oox+5;`G{tsN>;`M%;VX&)yaNq#)E(B$x59KkZ_>J0FZ%WbPJ86#Ii&$}RLgDjAI% z-fg4Mj7CPnjGsz^R4U{VRW$D&>6a*;OvtL=#7%7duFFt|d~+)i##HsJTyA>w@sN|z z=wwVWnyV<_R^!-3EH2@Sl^Fn@wNU9qz+{p^7y}?0#!>2e^y^c$ti_P=il;YDDtVj& zMN*btxUN>uYMct!QssK~tQ+})XPUWtb+9%~a~hq&B>cqJB<6hv6AjI&9-}%p8O>1M z3T{$9m0IHKEJiw212Zo;IIby3`dV04qE9Q9b~vix%DK-pk1G-0p)&G5UTcxQ=ci7V zgXWbmcmlC*u5#N!=~w1L;DNz4nD7;oEy=EF?sw6r6}eL8ZH^gN85GGRGAfb*9=?@s z_5}F(e`lC1X1$)(xNkMIKipFb(bM?kf!R~7=n zQIwE6W4&&v_BiK=mt9Ksy5_5EcMq3yBLyIU$0Ie>MdK^gW|5+g&69_I;^*w zJ!;5-OKl_auDDdGPiY=rB90!rO~Gm8baHsQ$lDu#v1Q0O%7O(I%(cJH7;YH#qPP0Z zNAVm{z|n&J-Pg_k0GaZ2hsFN@GYffa9D0iBbnl3|9m!MXeVxx^#S~Z6Cf3K|)G_#r zq~vw_XNjz?(;j3OQTjG3pwpx9oz6w}lM9C62pTtj@T zleeL-Ce=I#;*AF7qPWxU6_bOo6GauWsM|c}fukhdtWl3#)^w6XHN*@%Fe0{e-;6#W z)3)urkb&5-qKe+_9u-M<23pO{x?2B)Q7KHEv5l0NN_Xrj6Olvc;LM>NFLcAL3Y_e!zU?tq1YLZjzk zYdYt`nsxr@?Q;0*FKp38N3(>UsQW5ds_>@e8NYVN8RAa`-C10!+bdil9I}e#uQcnM z83b~~@t&YC>qQmg;%Gt_lux?KvkKMJVN+c<>IN^Dr!`f9#{-%uuNr67(vxH^jCsNO z)@~KE$vsb2lG4PH!qQ8HU;rH{*6_HH zhHQ{%qOvMZ&7(%$;()nk%Nj;zlpTyHqK_k)!7q4NrTZ*nZVP9e)HhdQz$JP1qKeI< zXj6^uB3!;Ux#`mtDoR*oSkXl!u4>^P#K^J}$0D>XP?h9lnkcOzv^c8ibWh}*VB}S+ zMP)fTIHHQ9hF=ZIm1K4#1=@XT%ob)u$CwoRQAKMQrg2V9Xp2zWwY-B5xEjA|j%Lns zJq;9A$#gg>N%FR9Tfy?4dGA8mznQ!tVe3T|x{7C$Ik@aAN04~qp%hU?MU5Psc0d2w D)E~C5 diff --git a/public/img/equipment_types/1629005722.jpg b/public/img/equipment_types/1629005722.jpg old mode 100644 new mode 100755 diff --git a/public/img/equipment_types/1629006269.jpg b/public/img/equipment_types/1629006269.jpg old mode 100644 new mode 100755 diff --git a/public/img/equipment_types/1629006425.jpg b/public/img/equipment_types/1629006425.jpg deleted file mode 100644 index 81303dcff5bf0a515e72cd7426e361ad51845256..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22202 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 b+YV0rUkf%4Ho}M0iyr;|^M7q%`FH$3@tM!v diff --git a/public/img/equipment_types/1629006847.jpg b/public/img/equipment_types/1629006847.jpg deleted file mode 100644 index 4d9dc50cda00bdb48bab63f0fe82c4da4acb4ed6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25139 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 '{id}', 'code' => '', 'title' => '{title} Resistor', 'quantity' => '{quantity}', 'specifications' => '1/4 W', 'formFactor' => '', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '12'),\n") + id += 1 +outputFile.write('\n') + +# SMD1206 Resistors +inputData = '''10 Ω 100 0.50 50.00 TRUE TRUE + 22 Ω 100 0.50 50.00 TRUE FALSE + 47 Ω 100 0.50 50.00 TRUE FALSE + 68 Ω 100 0.50 50.00 TRUE FALSE + 100 Ω 100 0.50 50.00 TRUE TRUE + 150 Ω 100 0.50 50.00 TRUE TRUE + 220 Ω 100 0.50 50.00 TRUE TRUE + 270 Ω 100 0.50 50.00 TRUE FALSE + 330 Ω 100 0.50 50.00 TRUE TRUE + 470 Ω 100 0.50 50.00 TRUE TRUE + 510 Ω 100 0.50 50.00 TRUE FALSE + 680 Ω 100 0.50 50.00 TRUE TRUE + 1KΩ 100 0.50 50.00 TRUE FALSE + 2.2 kΩ 100 0.50 50.00 TRUE TRUE + 3.3 kΩ 100 0.50 50.00 TRUE TRUE + 4.7 kΩ 100 0.50 50.00 TRUE TRUE + 5.1 kΩ 100 0.50 50.00 TRUE FALSE + 6.8 kΩ 100 0.50 50.00 TRUE TRUE + 10 kΩ 100 0.50 50.00 TRUE FALSE + 22 kΩ 100 0.50 50.00 TRUE TRUE + 33 kΩ 100 0.50 50.00 TRUE TRUE + 47 kΩ 100 0.50 50.00 TRUE TRUE + 51 kΩ 100 0.50 50.00 TRUE FALSE + 68 kΩ 100 0.50 50.00 TRUE TRUE + 100 kΩ 100 0.50 50.00 TRUE TRUE + 220 kΩ 100 0.50 50.00 TRUE TRUE + 330 kΩ 100 0.50 50.00 TRUE TRUE + 470 kΩ 100 0.50 50.00 TRUE TRUE + 510 kΩ 100 0.50 50.00 TRUE TRUE + 680 kΩ 100 0.50 50.00 TRUE TRUE + 1 MΩ 100 0.50 50.00 TRUE TRUE''' +for eachLine in inputData.split("\n"): + splitted = eachLine.split('\t') + title = splitted[0].replace(' ','') + + is_in_lab = True if (splitted[5] == "TRUE") else False + if (is_in_lab): + quantity = splitted[1] + else: + quantity = 0 + unit_price = splitted[2] + + outputFile.write(f"array('id' => '{id}', 'code' => '', 'title' => '{title} Resistor', 'quantity' => '{quantity}', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '13'),\n") + id += 1 + +outputFile.write('\n') + +# Electrolytic Capacitors +inputData = '''0.1 uF 50 1.50 75.00 TRUE FALSE + 0.22 uF 50 1.50 75.00 TRUE FALSE + 0.33 uF 50 1.50 75.00 TRUE FALSE + 0.47 uF 50 1.50 75.00 TRUE FALSE + 2.2 uF 50 1.50 75.00 TRUE FALSE + 3.3 uF 50 2.00 100.00 TRUE FALSE + 4.7 uF 50 2.00 100.00 TRUE FALSE + 10 uF 50 1.50 75.00 TRUE TRUE + 22 uF 50 1.50 75.00 TRUE TRUE + 47 uF 50 1.50 75.00 TRUE TRUE + 100 uF 50 3.00 150.00 TRUE TRUE + 220 uF 50 3.50 175.00 TRUE TRUE + 330 uF 50 3.00 150.00 TRUE TRUE + 470 uF 50 3.50 175.00 TRUE TRUE + 1000 uF 50 10.00 500.00 TRUE FALSE''' +for eachLine in inputData.split("\n"): + splitted = eachLine.split('\t') + title = splitted[0].replace(' ','') + + is_in_lab = True if (splitted[5] == "TRUE") else False + if (is_in_lab): + quantity = splitted[1] + else: + quantity = 0 + unit_price = splitted[2] + + outputFile.write(f"array('id' => '{id}', 'code' => '', 'title' => '{title} Capacitor', 'quantity' => '{quantity}', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '15'),\n") + id += 1 +outputFile.write('\n') + +# Ceramic Capacitors +inputData = '''10 pF 50 0.75 37.50 TRUE FALSE + 20 pF 50 0.75 37.50 TRUE FALSE + 30 pF 50 0.75 37.50 TRUE FALSE + 47 pF 50 0.75 37.50 TRUE FALSE + 68 pF 50 0.75 37.50 TRUE FALSE + 100 pF 50 0.75 37.50 TRUE FALSE + 220 pF 50 0.75 37.50 TRUE FALSE + 330 pF 50 0.75 37.50 TRUE FALSE + 470 pF 50 0.75 37.50 TRUE TRUE + 680 pF 50 0.75 37.50 TRUE FALSE + 1 nF 50 0.75 37.50 TRUE FALSE + 2.2 nF 50 0.75 37.50 TRUE FALSE + 3.3 nF 50 0.75 37.50 TRUE FALSE + 4.7 nF 50 0.75 37.50 TRUE FALSE + 6.8 nF 50 0.75 37.50 TRUE FALSE + 10 nF 50 0.75 37.50 TRUE FALSE + 22 nF 50 0.75 37.50 TRUE FALSE + 33 nF 50 0.75 37.50 TRUE FALSE + 47 nF 50 0.75 37.50 TRUE FALSE + 68 nF 50 0.75 37.50 TRUE FALSE + 100 nF 50 0.75 37.50 TRUE TRUE + 220 nF 50 0.75 37.50 TRUE FALSE + 330 nF 50 0.75 37.50 TRUE FALSE + 470 nF 50 0.75 37.50 TRUE FALSE + 680 nF 50 0.75 37.50 TRUE FALSE + 1 uF 50 0.75 37.50 TRUE FALSE + 2.2 uF 50 0.75 37.50 TRUE FALSE + 3.3 uF 50 0.75 37.50 TRUE FALSE + 4.7 uF 50 0.75 37.50 TRUE FALSE + 6.8 uF 50 0.75 37.50 TRUE FALSE''' +for eachLine in inputData.split("\n"): + splitted = eachLine.split('\t') + title = splitted[0].replace(' ','') + + is_in_lab = True if (splitted[5] == "TRUE") else False + if (is_in_lab): + quantity = splitted[1] + else: + quantity = 0 + unit_price = splitted[2] + + outputFile.write(f"array('id' => '{id}', 'code' => '', 'title' => '{title} Capacitor', 'quantity' => '{quantity}', 'specifications' => 'Through Hole', 'formFactor' => '', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '16'),\n") + id += 1 +outputFile.write('\n') + +inputData = '''1 pF 100 2.00 200.00 TRUE TRUE + 2.2 pF 100 3.00 300.00 TRUE FALSE + 3.3 pF 100 3.00 300.00 TRUE FALSE + 4.7 pF 100 3.00 300.00 TRUE FALSE + 6.8 pF 100 3.00 300.00 TRUE FALSE + 10 pF 100 2.00 200.00 TRUE TRUE + 22 pF 100 2.00 200.00 TRUE FALSE + 33 pF 100 3.00 300.00 TRUE FALSE + 47 pF 100 2.00 200.00 TRUE TRUE + 68 pF 100 3.00 300.00 TRUE FALSE + 100 pF 100 2.00 200.00 TRUE TRUE + 220 pF 100 2.00 200.00 TRUE TRUE + 330 pF 100 2.00 200.00 TRUE TRUE + 470 pF 100 2.00 200.00 TRUE TRUE + 680 pF 100 3.00 300.00 TRUE FALSE + 1 nF 100 2.00 200.00 TRUE TRUE + 2.2 nF 100 2.00 200.00 TRUE TRUE + 3.3 nF 100 2.00 200.00 TRUE TRUE + 4.7 nF 100 3.00 300.00 TRUE FALSE + 6.8 nF 100 3.00 300.00 TRUE FALSE + 10 nF 100 2.00 200.00 TRUE TRUE + 22 nF 100 3.00 300.00 TRUE FALSE + 33 nF 100 2.00 200.00 TRUE TRUE + 47 nF 100 2.00 200.00 TRUE TRUE + 68 nF 100 3.00 300.00 TRUE FALSE + 100 nF 100 2.00 200.00 TRUE TRUE + 220 nF 100 2.25 225.00 TRUE TRUE + 470 nF 100 3.00 300.00 TRUE TRUE + 680 nF 100 3.00 300.00 TRUE FALSE''' +for eachLine in inputData.split("\n"): + splitted = eachLine.split('\t') + title = splitted[0].replace(' ','') + + is_in_lab = True if (splitted[5] == "TRUE") else False + if (is_in_lab): + quantity = splitted[1] + else: + quantity = 0 + unit_price = splitted[2] + + outputFile.write(f"array('id' => '{id}', 'code' => '', 'title' => '{title} Capacitor', 'quantity' => '{quantity}', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'),\n") + id += 1 +outputFile.write('\n') + +# SMD1206 Capacitors +inputData = '''1 pF 100 2.00 200.00 TRUE TRUE + 2.2 pF 100 3.00 300.00 TRUE FALSE + 3.3 pF 100 3.00 300.00 TRUE FALSE + 4.7 pF 100 3.00 300.00 TRUE FALSE + 6.8 pF 100 3.00 300.00 TRUE FALSE + 10 pF 100 2.00 200.00 TRUE TRUE + 22 pF 100 2.00 200.00 TRUE FALSE + 33 pF 100 3.00 300.00 TRUE FALSE + 47 pF 100 2.00 200.00 TRUE TRUE + 68 pF 100 3.00 300.00 TRUE FALSE + 100 pF 100 2.00 200.00 TRUE TRUE + 220 pF 100 2.00 200.00 TRUE TRUE + 330 pF 100 2.00 200.00 TRUE TRUE + 470 pF 100 2.00 200.00 TRUE TRUE + 680 pF 100 3.00 300.00 TRUE FALSE + 1 nF 100 2.00 200.00 TRUE TRUE + 2.2 nF 100 2.00 200.00 TRUE TRUE + 3.3 nF 100 2.00 200.00 TRUE TRUE + 4.7 nF 100 3.00 300.00 TRUE FALSE + 6.8 nF 100 3.00 300.00 TRUE FALSE + 10 nF 100 2.00 200.00 TRUE TRUE + 22 nF 100 3.00 300.00 TRUE FALSE + 33 nF 100 2.00 200.00 TRUE TRUE + 47 nF 100 2.00 200.00 TRUE TRUE + 68 nF 100 3.00 300.00 TRUE FALSE + 100 nF 100 2.00 200.00 TRUE TRUE + 220 nF 100 2.25 225.00 TRUE TRUE + 470 nF 100 3.00 300.00 TRUE TRUE + 680 nF 100 3.00 300.00 TRUE FALSE''' +for eachLine in inputData.split("\n"): + splitted = eachLine.split('\t') + title = splitted[0].replace(' ','') + + is_in_lab = True if (splitted[5] == "TRUE") else False + if (is_in_lab): + quantity = splitted[1] + else: + quantity = 0 + unit_price = splitted[2] + + outputFile.write(f"array('id' => '{id}', 'code' => '', 'title' => '{title} Capacitor', 'quantity' => '{quantity}', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '17'),\n") + id += 1 +outputFile.write('\n') + +# Rectifier Diode +inputData = '''1N4001 30 1.50 45.00 TRUE TRUE + 1N4002 30 1.50 45.00 TRUE TRUE + 1N4003 30 3.00 90.00 TRUE TRUE + 1N4005 30 3.00 90.00 TRUE TRUE + 1N4007 30 3.00 90.00 TRUE TRUE''' +for eachLine in inputData.split("\n"): + splitted = eachLine.split('\t') + title = splitted[0].replace(' ','') + + is_in_lab = True if (splitted[5] == "TRUE") else False + if (is_in_lab): + quantity = splitted[1] + else: + quantity = 0 + unit_price = splitted[2] + + outputFile.write(f"array('id' => '{id}', 'code' => '', 'title' => '{title} Rectifier Diode', 'quantity' => '{quantity}', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '19'),\n") + id += 1 +outputFile.write('\n') + +# Zener Diodes +inputData = '''2V7 20 10.00 0 TRUE TRUE + 3V3 20 10.00 0 TRUE TRUE + 4V7 20 10.00 0 TRUE TRUE + 5V1 20 10.00 0 TRUE TRUE + 6V8 20 10.00 0 TRUE TRUE + 8V2 20 10.00 0 TRUE TRUE + 10V 20 10.00 0 TRUE TRUE + 12V 20 10.00 0 TRUE TRUE + 20V 20 10.00 0 TRUE TRUE''' +for eachLine in inputData.split("\n"): + splitted = eachLine.split('\t') + title = splitted[0].replace(' ','') + + is_in_lab = True if (splitted[5] == "TRUE") else False + if (is_in_lab): + quantity = splitted[1] + else: + quantity = 0 + unit_price = splitted[2] + + outputFile.write(f"array('id' => '{id}', 'code' => '', 'title' => '{title} Zener Diode', 'quantity' => '{quantity}', 'specifications' => '', 'formFactor' => '1206', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '20'),\n") + id += 1 +outputFile.write('\n') + +# Headers +inputData = '''Straight 40 pin Male (Black) 30 12.00 360.00 TRUE TRUE + Straight 2x40 pin Male (Black) 20 16.00 320.00 TRUE FALSE + Straight 40 pin Male (Red) 10 16.00 160.00 TRUE FALSE + Straight 40 pin Male (Yellow) 10 16.00 160.00 TRUE FALSE + Straight 40 pin Male (Green) 10 16.00 160.00 TRUE FALSE + Female 40 pin 40 20.00 800.00 TRUE TRUE + Female 2x40 pin 20 45.00 900.00 TRUE TRUE''' +for eachLine in inputData.split("\n"): + splitted = eachLine.split('\t') + title = splitted[0].replace(' ','') + + is_in_lab = True if (splitted[5] == "TRUE") else False + if (is_in_lab): + quantity = splitted[1] + else: + quantity = 0 + unit_price = splitted[2] + + outputFile.write(f"array('id' => '{id}', 'code' => '', 'title' => '{title}', 'quantity' => '{quantity}', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '22'),\n") + id += 1 +outputFile.write('\n') + +# LEDs +inputData = '''Red (5mm, Diffused) 100 1.75 175.00 TRUE TRUE + Green (5mm, Diffused) 100 2.00 200.00 TRUE TRUE + Blue (5mm, Diffused) 100 2.00 200.00 TRUE TRUE + Yellow (5mm, Diffused) 100 2.00 200.00 TRUE TRUE + White (5mm, Clean White) 50 2.00 100.00 TRUE TRUE + Infrared (5mm) 30 9.00 270.00 TRUE FALSE + Ultraviolet (5mm) 30 12.00 360.00 TRUE FALSE''' +for eachLine in inputData.split("\n"): + splitted = eachLine.split('\t') + title = splitted[0].replace(' ','') + + is_in_lab = True if (splitted[5] == "TRUE") else False + if (is_in_lab): + quantity = splitted[1] + else: + quantity = 0 + unit_price = splitted[2] + + outputFile.write(f"array('id' => '{id}', 'code' => '', 'title' => '{title} LED', 'quantity' => '{quantity}', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '23'),\n") + id += 1 +outputFile.write('\n') + +# Single Core Wire +inputData = '''Red 25 15.00 375.00 TRUE TRUE + Black 25 15.00 375.00 TRUE TRUE + Yellow 25 15.00 375.00 TRUE TRUE''' +for eachLine in inputData.split("\n"): + splitted = eachLine.split('\t') + title = splitted[0].replace(' ','') + + is_in_lab = True if (splitted[5] == "TRUE") else False + if (is_in_lab): + quantity = splitted[1] + else: + quantity = 0 + unit_price = splitted[2] + + outputFile.write(f"array('id' => '{id}', 'code' => '', 'title' => '{title} Single Core Wire', 'quantity' => '{quantity}', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '27'),\n") + id += 1 +outputFile.write('\n') + +# Circuit Wire +inputData = '''Red 1 10.00 1,000.00 TRUE TRUE TRUE + Black 1 10.00 1,000.00 TRUE TRUE TRUE + White 1 10.00 1,000.00 TRUE TRUE TRUE + Green 1 10.00 1,000.00 TRUE TRUE TRUE + Orange 1 10.00 1,000.00 TRUE TRUE TRUE + Blue 1 10.00 1,000.00 TRUE TRUE TRUE''' +for eachLine in inputData.split("\n"): + splitted = eachLine.split('\t') + title = splitted[0].replace(' ','') + + is_in_lab = True if (splitted[5] == "TRUE") else False + if (is_in_lab): + quantity = splitted[1] + else: + quantity = 0 + unit_price = splitted[2] + + outputFile.write(f"array('id' => '{id}', 'code' => '', 'title' => '{title} Circuit Wire', 'quantity' => '{quantity}', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '29'),\n") + id += 1 +outputFile.write('\n') + +# IC Base +inputData = '''10 pin 20 8.00 120.00 TRUE FALSE + 12 pin 20 10.00 120.00 TRUE FALSE + 14 pin 20 6.00 120.00 TRUE TRUE + 16 pin 20 6.00 120.00 TRUE TRUE + 18 pin 20 6.00 120.00 TRUE TRUE''' +for eachLine in inputData.split("\n"): + splitted = eachLine.split('\t') + title = splitted[0].replace(' ','') + + is_in_lab = True if (splitted[5] == "TRUE") else False + if (is_in_lab): + quantity = splitted[1] + else: + quantity = 0 + unit_price = splitted[2] + + outputFile.write(f"array('id' => '{id}', 'code' => '', 'title' => '{title} IC Base', 'quantity' => '{quantity}', 'specifications' => '', 'formFactor' => 'DIP, 0.1\"', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '25'),\n") + id += 1 +outputFile.write('\n') + +# Logic ICs +inputData = '''7400 12 38.00 456.00 TRUE TRUE + 7408 12 36.00 432.00 TRUE TRUE + 7486 12 54.00 648.00 TRUE FALSE + 7404 12 36.00 432.00 TRUE FALSE + 7402 12 50.00 600.00 TRUE FALSE + 7432 12 50.00 600.00 TRUE FALSE + 7410 6 85.00 510.00 TRUE FALSE + 7411 6 95.00 570.00 TRUE FALSE + 7427 6 295.00 1,770.00 TRUE FALSE''' +for eachLine in inputData.split("\n"): + splitted = eachLine.split('\t') + title = splitted[0].replace(' ','') + + is_in_lab = True if (splitted[5] == "TRUE") else False + if (is_in_lab): + quantity = splitted[1] + else: + quantity = 0 + unit_price = splitted[2] + + outputFile.write(f"array('id' => '{id}', 'code' => '', 'title' => '{title} Logic IC', 'quantity' => '{quantity}', 'specifications' => 'Logic ICs', 'formFactor' => 'DIP, 0.1\"', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '31'),\n") + id += 1 +outputFile.write('\n') + +# 74xxx ICs +inputData = '''7447 6 120.00 720.00 TRUE FALSE + 7491 2 580.00 1,160.00 TRUE FALSE + 7476 3 365.00 1,095.00 TRUE FALSE + 74138 4 22.00 132.00 TRUE TRUE + 74139 6 36.00 216.00 TRUE FALSE + 74157 6 72.00 432.00 TRUE TRUE + 74244 6 60.00 360.00 TRUE TRUE + 74245 4 54.00 216.00 TRUE TRUE + 74273 3 42.00 126.00 TRUE TRUE + 74283 4 174.00 696.00 TRUE TRUE + 74173 3 360.00 1,080.00 TRUE FALSE''' +for eachLine in inputData.split("\n"): + splitted = eachLine.split('\t') + title = splitted[0].replace(' ','') + + is_in_lab = True if (splitted[5] == "TRUE") else False + if (is_in_lab): + quantity = splitted[1] + else: + quantity = 0 + unit_price = splitted[2] + + outputFile.write(f"array('id' => '{id}', 'code' => '', 'title' => '{title} IC', 'quantity' => '{quantity}', 'specifications' => '', 'formFactor' => 'DIP, 0.1\"', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '32'),\n") + id += 1 +outputFile.write('\n') + +# Other ICs +inputData = '''NE555 7 15.00 105.00 TRUE TRUE + UA741 12 15.00 180.00 TRUE TRUE + L293 4 138.00 552.00 TRUE FALSE + LM324 12 30.00 360.00 TRUE FALSE + MAX232 6 50.00 300.00 TRUE FALSE + ULN2003 10 45.00 450.00 TRUE FALSE''' +for eachLine in inputData.split("\n"): + splitted = eachLine.split('\t') + title = splitted[0].replace(' ','') + + is_in_lab = True if (splitted[5] == "TRUE") else False + if (is_in_lab): + quantity = splitted[1] + else: + quantity = 0 + unit_price = splitted[2] + + outputFile.write(f"array('id' => '{id}', 'code' => '', 'title' => '{title} IC', 'quantity' => '{quantity}', 'specifications' => '', 'formFactor' => 'DIP, 0.1\"', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '33'),\n") + id += 1 +outputFile.write('\n') + +# Power Regulators +inputData = '''7805 10 24.00 240.00 TRUE TRUE + 7806 10 20.00 200.00 TRUE FALSE + 7812 10 28.00 280.00 TRUE TRUE + AMS 1117 3.3V 20 17.00 340.00 TRUE FALSE + AMS 1117 5V 20 12.00 240.00 TRUE FALSE''' +for eachLine in inputData.split("\n"): + splitted = eachLine.split('\t') + title = splitted[0].replace(' ','') + + is_in_lab = True if (splitted[5] == "TRUE") else False + if (is_in_lab): + quantity = splitted[1] + else: + quantity = 0 + unit_price = splitted[2] + + outputFile.write(f"array('id' => '{id}', 'code' => '', 'title' => '{title} Power Regulator', 'quantity' => '{quantity}', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '34'),\n") + id += 1 + +outputFile.write('\n') + +# Transistors +inputData = '''2N2222 20 4.00 80.00 TRUE FALSE + C828 20 5.00 1000.00 TRUE FALSE + A733 20 9.00 180.00 TRUE TRUE + BC107 20 20.00 400.00 TRUE FALSE + BC556 20 3.00 60.00 TRUE TRUE + S8550 20 8.00 160.00 TRUE FALSE + S9012 20 2.50 50.00 TRUE TRUE + IRF520N 20 60.00 1,200.00 TRUE TRUE + IRF9530N 20 66.00 1,320.00 TRUE TRUE''' +for eachLine in inputData.split("\n"): + splitted = eachLine.split('\t') + title = splitted[0].replace(' ','') + + is_in_lab = True if (splitted[5] == "TRUE") else False + if (is_in_lab): + quantity = splitted[1] + else: + quantity = 0 + unit_price = splitted[2] + + outputFile.write(f"array('id' => '{id}', 'code' => '', 'title' => '{title} Transistor', 'quantity' => '{quantity}', 'specifications' => '', 'formFactor' => 'Through Hole', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '35'),\n") + id += 1 + +outputFile.write('\n') + +# Crystal Oscillators +inputData = '''4MHz 6 14.00 84.00 TRUE TRUE + 8MHz 6 14.00 84.00 TRUE FALSE + 12MHz 6 14.00 84.00 TRUE TRUE + 16MHz 6 15.00 90.00 TRUE FALSE + 20MHz 6 14.00 84.00 TRUE FALSE + 32MHz 6 15.00 90.00 TRUE FALSE''' +for eachLine in inputData.split("\n"): + splitted = eachLine.split('\t') + title = splitted[0].replace(' ','') + + is_in_lab = True if (splitted[5] == "TRUE") else False + if (is_in_lab): + quantity = splitted[1] + else: + quantity = 0 + unit_price = splitted[2] + + outputFile.write(f"array('id' => '{id}', 'code' => '', 'title' => '{title} Crystal Oscillator', 'quantity' => '{quantity}', 'specifications' => '', 'formFactor' => 'Through Hole', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '36'),\n") + id += 1 +outputFile.write('\n') + +# DIP Switches +inputData = '''3P 20 22.00 440.00 TRUE TRUE + 4P 20 24.00 480.00 TRUE TRUE + 5P 20 28.00 560.00 TRUE TRUE + 6P 20 30.00 600.00 TRUE TRUE + 8P 20 34.00 680.00 TRUE TRUE''' +for eachLine in inputData.split("\n"): + splitted = eachLine.split('\t') + title = splitted[0].replace(' ','') + + is_in_lab = True if (splitted[5] == "TRUE") else False + if (is_in_lab): + quantity = splitted[1] + else: + quantity = 0 + unit_price = splitted[2] + + outputFile.write(f"array('id' => '{id}', 'code' => '', 'title' => '{title} DIP Switch', 'quantity' => '{quantity}', 'specifications' => '', 'formFactor' => 'DIP, 0.1\"', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '38'),\n") + id += 1 + +outputFile.write('\n') + +# Ports +inputData = '''USB Socket - A Type Female 15 18.00 270.00 TRUE FALSE + USB Socket - A Type Male 15 16.00 240.00 TRUE FALSE + DC Jack 2.1x5.5mm 20 18.00 360.00 TRUE TRUE + DC Barrel Socket 2.1x5.5mm 20 7.00 140.00 TRUE FALSE + Crocodile Clip - Red 25 19.00 475.00 TRUE FALSE + Crocodile Clip - Black 25 19.00 475.00 TRUE FALSE''' +for eachLine in inputData.split("\n"): + splitted = eachLine.split('\t') + title = splitted[0].replace(' ','') + + is_in_lab = True if (splitted[5] == "TRUE") else False + if (is_in_lab): + quantity = splitted[1] + else: + quantity = 0 + unit_price = splitted[2] + + outputFile.write(f"array('id' => '{id}', 'code' => '', 'title' => '{title} Port', 'quantity' => '{quantity}', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '39'),\n") + id += 1 + +outputFile.write('\n') + +# Trimpots +inputData = '''500 Ω 15 15.00 225.00 TRUE TRUE + 1 kΩ 15 15.00 225.00 TRUE TRUE + 2 kΩ 15 15.00 225.00 TRUE TRUE + 5 kΩ 15 15.00 225.00 TRUE TRUE + 10 kΩ 15 15.00 225.00 TRUE TRUE + 20 kΩ 15 15.00 225.00 TRUE TRUE + 50 kΩ 15 15.00 225.00 TRUE TRUE + 100 kΩ 15 15.00 225.00 TRUE TRUE + 220 kΩ 15 15.00 225.00 TRUE TRUE + 500 kΩ 15 15.00 225.00 TRUE TRUE''' + +for eachLine in inputData.split("\n"): + splitted = eachLine.split('\t') + title = splitted[0].replace(' ','') + + is_in_lab = True if (splitted[5] == "TRUE") else False + if (is_in_lab): + quantity = splitted[1] + else: + quantity = 0 + unit_price = splitted[2] + + outputFile.write(f"array('id' => '{id}', 'code' => '', 'title' => '{title} Trimpot', 'quantity' => '{quantity}', 'specifications' => '', 'formFactor' => '', 'datasheetURL' => '', 'price' => '{unit_price}', 'thumb' => NULL, 'created_at' => '2021-08-04 15:23:56', 'updated_at' => '2021-09-02 05:41:38', 'consumable_type_id' => '40'),\n") + id += 1 diff --git a/python_scripts/item_locations.py b/python_scripts/item_locations.py new file mode 100755 index 00000000..162d55a2 --- /dev/null +++ b/python_scripts/item_locations.py @@ -0,0 +1,223 @@ +# $all = \App\Models\EquipmentItem::all(); +# foreach ($all as $each){ +# echo $each->inventoryCode() . "\n"; +# } +# +# $all = \App\Models\ComponentItem::all(); +# foreach ($all as $each){ +# echo $each->inventoryCode() . "\n"; +# } +# +# $all = \App\Models\Machines::all(); +# foreach ($all as $each){ +# echo $each->inventoryCode() . "\n"; +# } +# +# $all = \App\Models\ConsumableItem::all(); +# foreach ($all as $each){ +# echo $each->inventoryCode() . "\n"; +# } + +inventory_codes = """EQ/17/1000 + EQ/17/1001 + EQ/17/1002 + EQ/17/1003 + EQ/17/1004 + EQ/17/1005 + EQ/17/1006 + EQ/17/1007 + EQ/17/1008 + EQ/17/1009 + EQ/17/1010 + EQ/17/1011 + EQ/17/1012 + EQ/17/1013 + EQ/17/1014 + EQ/17/1015 + EQ/17/1016 + EQ/17/1017 + EQ/24/1018 + EQ/17/1019 + EQ/25/1020 + EQ/25/1021 + EQ/22/1022 + EQ/19/1023 + EQ/11/1024 + EQ/13/1025 + EQ/15/1026 + EQ/15/1027 + EQ/15/1028 + EQ/15/1029 + EQ/22/1030 + EQ/22/1031 + EQ/11/1032 + EQ/11/1033 + EQ/18/1034 + EQ/18/1035 + EQ/18/1036 + EQ/17/1037 + EQ/17/1038 + EQ/17/1039 + EQ/19/1040 + EQ/19/1041 + EQ/22/1042 + EQ/23/1043 + EQ/22/1044 + EQ/21/1045 + EQ/17/1046 + EQ/20/1047 + EQ/20/1048 + EQ/20/1049 + EQ/20/1050 + EQ/20/1051 + EQ/20/1052 + EQ/19/1053 + CM/16/1001 + CM/17/1002 + MC/001 + MC/002 + MS/CS/12/1001 + MS/CS/12/1002 + MS/CS/12/1003 + MS/CS/12/1004 + MS/CS/12/1005 + MS/CS/12/1006 + MS/CS/12/1007 + MS/CS/12/1008 + MS/CS/12/1009 + MS/CS/12/1010 + MS/CS/12/1011 + MS/CS/12/1012 + MS/CS/12/1013 + MS/CS/12/1014 + MS/CS/12/1015 + MS/CS/12/1016 + MS/CS/12/1017 + MS/CS/12/1018 + MS/CS/12/1019 + MS/CS/12/1020 + MS/CS/12/1021 + MS/CS/12/1022 + MS/CS/12/1023 + MS/CS/12/1024 + MS/CS/12/1025 + MS/CS/12/1026 + MS/CS/12/1027 + MS/CS/12/1028 + MS/CS/12/1029 + MS/CS/13/1030 + MS/CS/13/1031 + MS/CS/13/1032 + MS/CS/13/1033 + MS/CS/13/1034 + MS/CS/13/1035 + MS/CS/13/1036 + MS/CS/13/1037 + MS/CS/13/1038 + MS/CS/13/1039 + MS/CS/13/1040 + MS/CS/13/1041 + MS/CS/13/1042 + MS/CS/13/1043 + MS/CS/13/1044 + MS/CS/13/1045 + MS/CS/13/1046 + MS/CS/13/1047 + MS/CS/13/1048 + MS/CS/13/1049 + MS/CS/13/1050 + MS/CS/13/1051 + MS/CS/15/1052 + MS/CS/15/1053 + MS/CS/15/1054 + MS/CS/15/1055 + MS/CS/15/1056 + MS/CS/15/1057 + MS/CS/15/1058 + MS/CS/16/1059 + MS/CS/16/1060 + MS/CS/17/1061 + MS/CS/17/1062 + MS/CS/17/1063 + MS/CS/17/1064 + MS/CS/17/1065 + MS/CS/17/1066 + MS/CS/17/1067 + MS/CS/17/1068 + MS/CS/17/1069 + MS/CS/17/1070 + MS/CS/17/1071 + MS/CS/17/1072 + MS/CS/17/1073 + MS/CS/17/1074 + MS/CS/17/1075 + MS/CS/17/1076 + MS/CS/17/1077 + MS/CS/17/1078 + MS/CS/17/1079 + MS/CS/17/1080 + MS/CS/17/1081 + MS/CS/17/1082 + MS/CS/17/1083 + MS/CS/17/1084 + MS/CS/17/1085 + MS/CS/17/1086 + MS/CS/17/1087 + MS/CS/17/1088 + MS/CS/17/1089 + MS/CS/17/1090 + MS/CS/17/1091 + MS/CS/17/1092 + MS/CS/19/1093 + MS/CS/19/1094 + MS/CS/22/1095 + MS/CS/22/1096 + MS/CS/24/1097 + MS/CS/24/1098 + MS/CS/24/1099 + MS/CS/24/1100 + MS/CS/24/1101 + MS/CS/27/1102 + MS/CS/27/1103 + MS/CS/31/1104 + MS/CS/31/1105 + MS/CS/32/1106 + MS/CS/32/1107 + MS/CS/32/1108 + MS/CS/32/1109 + MS/CS/32/1110 + MS/CS/32/1111 + MS/CS/33/1112 + MS/CS/33/1113 + MS/CS/34/1114 + MS/CS/34/1115 + MS/CS/35/1116 + MS/CS/35/1117 + MS/CS/35/1118 + MS/CS/35/1119 + MS/CS/35/1120 + MS/CS/36/1121 + MS/CS/36/1122 + MS/CS/38/1123 + MS/CS/38/1124 + MS/CS/38/1125 + MS/CS/38/1126 + MS/CS/38/1127 + MS/CS/39/1128 + RW/001 + RW/002 + RW/003 + RW/004 + RW/005 + RW/006 + RW/007 +""" + +location_id = 0 +id = 0 +for each in inventory_codes.split(): + print(f"array('id' => '{id}', 'location_id' => {location_id}, 'item_id' => '{each}'),") + id += 1 + location_id += 1 + if location_id == 3: + location_id = 0 \ No newline at end of file diff --git a/python_scripts/output b/python_scripts/output new file mode 100755 index 0000000000000000000000000000000000000000..94f7f6af298d17c18854257f51a8f21c169b3991 GIT binary patch literal 27884 zcmcJXO^YN|5Jlfw@ISa~g#kN1DnAywX@>E?vkp z1Jgb(?_{2gdKpoF{_(c`cKr9Y{oX!p5AEmnh`1#Ntk3VmYzs28wY46() z$8UZ(e(QbvwSE7O-+nxQGuHUferoUj_3sbutM+yKybWzVe?A_o$NHZg|KG>$qhsa& zOEQ2YgOMcG*OH7N$!H{r^|d4uNaE0m^|d53NaE0m^|d4yki?-A>uX6Cki?-A>uX6? zki?-A>uX6iki?-A>uX7Nki?-A>uX5{WLeH9*H^O;&vHV;VSjyJh-o>aq3Na_8gZ?| zNO$efh;1E4x^0I>eCsgMeLFN_T!)cv+^BK%%E@7*J9lWrx+{)d0 z#ucyM)9QT`PsE-@_im8Yv#5;XDc7^;-W`#5bw+g`>E0cYcXdXUMfdKAysI;+EV_3` z!FqI-8n z-qjiPS}NDq7|qDLI-|;>dv`|ORTyn`nDL413gO=Zx}#4gCQx0yV*Z;yR=I)BDHku*Qs zm9U|DVyKXLIg!3c3v#Z)>E%TF>EVLR>r>Nfss+`(J~jOl?Q&XDy^efp`sdmOx!9+s zS6K@(vQJH~wU$>thxjia=@r-V%BK-8CnE3F7vyZ08hN|EpbFW&*T_5e6*=3z*YZui zRu!(u**-Ph*(-9kPfd6Bik$6J)1AE{XZzH2XRpZFJ~iFhD{{6^O?UQ+ob6I0@8nnH zY?oTT`B!~J>TH)#m&pPF80Z^+p`HQm`8a<)%RclL&y?Nig8y&-4&)O2TW z$k{$M-Ps#*wogrW_J*8Isr7dj$k{$M-Pt>GwogrW_KuwGQ`4QjBWJtRNH4&Sob6J}jsvaE z-jTCiYNRh9&YH+9p3hCUcJ_YX@7%vX+p-TqBNv(CNqDa_Gs zU1cI3XH$eeJL2(to1i{he0Id+Y^u;_M?B7^3w?IP<7~>%XGc8FrVV{|q#kEehc3J9 zk5HY-rVm|q*&(54A|7|yWsiiKiA^K=?1;zNRHDz0c$`fq`s|3ubBa)Xw)pIb$8(xc z&E&Hq9-r=duF`9j?3d8*yL+CiR3_qaHpS?&%bp2+pGZCK-gntGp=Tl*^zoYrxn$G^6xw1 z@fn?uyX>-$LcgAf$6a>WNug&V9(UPgFNKK7-jzCS{ksYrV5V&BUfMDZ9!bV zSDA>%*=#0dm%SmePsHPFI+L=iOvK}CK9jPmOvK}CLepnQJkDk`U3O$fGdgI9$0@t) zp^0t}Qjf2w9;fUo6RF49q$XvT-x(SEL_E%BH7UEwL_E%>H7UEwL_E&sHGOu(<7{Hn zXGc8FW;Q9iJg19moOql~ZQf@0P5bWn{KUSsD!%JB_E9}?x=pK6Fb5G=-{w;(m~~$F ew4_oH&#);>LWG!wO Vue.component(key.split('/').pop().split('.')[0], files(key).default)) -Vue.component('example-component', require('./components/ExampleComponent.vue').default); +/* +Vue.component( + 'example-component', + require('./components/ExampleComponent.vue').default +) +*/ /** * Next, we will create a fresh Vue application instance and attach it to @@ -30,4 +35,4 @@ Vue.component('example-component', require('./components/ExampleComponent.vue'). const app = new Vue({ el: '#app', -}); +}) diff --git a/resources/js/frontend/components/ExampleComponent.vue b/resources/js/frontend/components/ExampleComponent.vue deleted file mode 100644 index 79bd6c45..00000000 --- a/resources/js/frontend/components/ExampleComponent.vue +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/resources/js/frontend/components/ScheduleCalendar.vue b/resources/js/frontend/components/ScheduleCalendar.vue new file mode 100755 index 00000000..bc9efdc5 --- /dev/null +++ b/resources/js/frontend/components/ScheduleCalendar.vue @@ -0,0 +1,274 @@ + + + \ No newline at end of file diff --git a/resources/js/plugins.js b/resources/js/plugins.js old mode 100644 new mode 100755 diff --git a/resources/lang/en/auth.php b/resources/lang/en/auth.php old mode 100644 new mode 100755 diff --git a/resources/lang/en/pagination.php b/resources/lang/en/pagination.php old mode 100644 new mode 100755 diff --git a/resources/lang/en/passwords.php b/resources/lang/en/passwords.php old mode 100644 new mode 100755 diff --git a/resources/lang/en/validation.php b/resources/lang/en/validation.php old mode 100644 new mode 100755 diff --git a/resources/sass/_global.scss b/resources/sass/_global.scss old mode 100644 new mode 100755 diff --git a/resources/sass/app.scss b/resources/sass/app.scss old mode 100644 new mode 100755 diff --git a/resources/sass/backend/app.scss b/resources/sass/backend/app.scss old mode 100644 new mode 100755 index 2d631bce..4c3b482f --- a/resources/sass/backend/app.scss +++ b/resources/sass/backend/app.scss @@ -1,6 +1,7 @@ @import "../global"; @import "backend.css"; -// Coreui +// CoreUI @import '~@coreui/coreui/scss/coreui'; @import '~@coreui/icons/css/free.min.css'; +@import '~@coreui/icons/css/brand.min.css'; diff --git a/resources/sass/backend/backend.css b/resources/sass/backend/backend.css old mode 100644 new mode 100755 diff --git a/resources/sass/frontend/_global.scss b/resources/sass/frontend/_global.scss old mode 100644 new mode 100755 diff --git a/resources/sass/frontend/_variables.scss b/resources/sass/frontend/_variables.scss old mode 100644 new mode 100755 diff --git a/resources/sass/frontend/app.scss b/resources/sass/frontend/app.scss old mode 100644 new mode 100755 index c2682031..3879de25 --- a/resources/sass/frontend/app.scss +++ b/resources/sass/frontend/app.scss @@ -6,4 +6,9 @@ @import 'variables'; // Bootstrap -@import '~bootstrap/scss/bootstrap'; +// @import '~bootstrap/scss/bootstrap'; + +// CoreUI +@import '~@coreui/coreui/scss/coreui'; +@import '~@coreui/icons/css/free.min.css'; +@import '~@coreui/icons/css/brand.min.css'; diff --git a/resources/sass/frontend/frontend.css b/resources/sass/frontend/frontend.css old mode 100644 new mode 100755 diff --git a/resources/views/backend/announcements/create.blade.php b/resources/views/backend/announcements/create.blade.php new file mode 100755 index 00000000..52603283 --- /dev/null +++ b/resources/views/backend/announcements/create.blade.php @@ -0,0 +1,101 @@ +@extends('backend.layouts.app') + +@section('title', __('Announcements')) + +@section('content') +

+ {!! Form::open(['url' => route('admin.announcements.store'), + 'method' => 'post', + 'class' => 'container', + 'files'=>true, + 'enctype'=>'multipart/form-data' + ]) !!} + + + + Announcements : Create + + + + +
+ {!! Form::label('area', 'Area*', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::select('area', $areas, null, ['class'=>'form-control', 'required'=>true, 'placeholder' => '']) !!} + @error('area') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('type', 'Type*', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::select('type', $types, null, ['class'=>'form-control', 'required'=>true, 'placeholder' => '']) !!} + @error('type') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('message', 'Display Message*', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::textarea('message', '', ['class'=>'form-control', 'rows'=>3, 'required'=>true, ]) !!} + @error('message') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('enabled', 'Enabled*', ['class' => 'col-md-2 form-check-label']) !!} + +
+ {!! Form::checkbox('enabled', '1', ['class'=>'form-check-input', 'required'=>true,]) !!} + @error('enabled') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('starts_at', 'Starts at*', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::datetimeLocal('starts_at', '', ['class'=>'form-control', 'required'=>true,]) !!} + @error('starts_at') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('ends_at', 'Ends at*', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::datetimeLocal('ends_at', '', ['class'=>'form-control', 'required'=>true,]) !!} + @error('ends_at') + {{ $message }} + @enderror +
+
+
+ + + {!! Form::submit('Create', ['class'=>'btn btn-primary float-right']) !!} + + +
+ + {!! Form::close() !!} +
+@endsection diff --git a/resources/views/backend/announcements/delete.blade.php b/resources/views/backend/announcements/delete.blade.php new file mode 100755 index 00000000..b129b9df --- /dev/null +++ b/resources/views/backend/announcements/delete.blade.php @@ -0,0 +1,27 @@ +@extends('backend.layouts.app') + +@section('title', __('Announcement')) + +@section('content') +
+@endsection diff --git a/resources/views/backend/announcements/edit.blade.php b/resources/views/backend/announcements/edit.blade.php new file mode 100755 index 00000000..ba4d6f59 --- /dev/null +++ b/resources/views/backend/announcements/edit.blade.php @@ -0,0 +1,102 @@ +@extends('backend.layouts.app') + +@section('title', __('Announcements')) + +@section('content') +
+ {!! Form::open(['url' => route('admin.announcements.update', + compact('announcement')), + 'method' => 'put', + 'class' => 'container', + 'files'=>true, + 'enctype'=>'multipart/form-data' + ]) !!} + + + + Announcements : Edit | {{ $announcement->id }} + + + + +
+ {!! Form::label('area', 'Area*', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::select('area', $areas, $announcement->area, ['class'=>'form-control', 'required'=>true, 'placeholder' => '']) !!} + @error('area') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('type', 'Type*', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::select('type', $types, $announcement->type, ['class'=>'form-control', 'required'=>true, 'placeholder' => '']) !!} + @error('type') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('message', 'Display Message*', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::textarea('message', $announcement->message, ['class'=>'form-control', 'rows'=>3, 'required'=>true, ]) !!} + @error('message') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('enabled', 'Enabled*', ['class' => 'col-md-2 form-check-label']) !!} + +
+ enabled == 1 ? 'checked' :''}} /> + @error('enabled') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('starts_at', 'Starts at*', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::datetimeLocal('starts_at', $announcement->starts_at, ['class'=>'form-control', 'required'=>true,]) !!} + @error('starts_at') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('ends_at', 'Ends at*', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::datetimeLocal('ends_at', $announcement->ends_at, ['class'=>'form-control', 'required'=>true,]) !!} + @error('ends_at') + {{ $message }} + @enderror +
+
+ +
+ + {!! Form::submit('Update', ['class'=>'btn btn-primary float-right']) !!} + + +
+ {!! Form::close() !!} +
+@endsection diff --git a/resources/views/backend/announcements/index-table-row.blade.php b/resources/views/backend/announcements/index-table-row.blade.php new file mode 100755 index 00000000..129a5c64 --- /dev/null +++ b/resources/views/backend/announcements/index-table-row.blade.php @@ -0,0 +1,42 @@ + + @if ($row->area == App\Domains\Announcement\Models\Announcement::TYPE_FRONTEND) + Frontend + @elseif($row->area == App\Domains\Announcement\Models\Announcement::TYPE_BACKEND) + Backend + @else + Both + @endif + + + + {{ App\Domains\Announcement\Models\Announcement::types()[$row->type] }} + + + + {{ $row->message }} + + + + {{ $row->enabled ? 'Enabled' : 'Disabled' }} + + + + {{ $row->starts_at }} + + + + {{ $row->ends_at }} + + + +
+
+ + + + +
+
+
diff --git a/resources/views/backend/announcements/index.blade.php b/resources/views/backend/announcements/index.blade.php new file mode 100755 index 00000000..8aad885e --- /dev/null +++ b/resources/views/backend/announcements/index.blade.php @@ -0,0 +1,31 @@ +@extends('backend.layouts.app') + +@section('title', __('Manage')) + +@section('content') +
+ + + Announcements + + + @if ($logged_in_user->hasInventoryAccess()) + + + + + @endif + + + + @if (session('Success')) + + {{ session('Success') }} + + @endif + + + + +
+@endsection diff --git a/resources/views/backend/auth/includes/partials/permission-type.blade.php b/resources/views/backend/auth/includes/partials/permission-type.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/auth/includes/partials/role-type.blade.php b/resources/views/backend/auth/includes/partials/role-type.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/auth/includes/permissions.blade.php b/resources/views/backend/auth/includes/permissions.blade.php old mode 100644 new mode 100755 index 3a7eba89..724d71f0 --- a/resources/views/backend/auth/includes/permissions.blade.php +++ b/resources/views/backend/auth/includes/permissions.blade.php @@ -11,5 +11,18 @@
@include('backend.auth.includes.partials.permission-type', ['type' => $model::TYPE_USER])
+ +
+ @include('backend.auth.includes.partials.permission-type', ['type' => $model::TYPE_LECTURER]) +
+ +
+ @include('backend.auth.includes.partials.permission-type', ['type' => $model::TYPE_TECH_OFFICER]) +
+ +
+ @include('backend.auth.includes.partials.permission-type', ['type' => $model::TYPE_MAINTAINER]) +
+ diff --git a/resources/views/backend/auth/includes/roles.blade.php b/resources/views/backend/auth/includes/roles.blade.php old mode 100644 new mode 100755 index 9e74dd33..c405eed2 --- a/resources/views/backend/auth/includes/roles.blade.php +++ b/resources/views/backend/auth/includes/roles.blade.php @@ -9,5 +9,17 @@
@include('backend.auth.includes.partials.role-type', ['type' => $model::TYPE_USER])
+ +
+ @include('backend.auth.includes.partials.role-type', ['type' => $model::TYPE_LECTURER]) +
+ +
+ @include('backend.auth.includes.partials.role-type', ['type' => $model::TYPE_TECH_OFFICER]) +
+ +
+ @include('backend.auth.includes.partials.role-type', ['type' => $model::TYPE_MAINTAINER]) +
diff --git a/resources/views/backend/auth/role/create.blade.php b/resources/views/backend/auth/role/create.blade.php old mode 100644 new mode 100755 index 44f5a44f..d3966f0d --- a/resources/views/backend/auth/role/create.blade.php +++ b/resources/views/backend/auth/role/create.blade.php @@ -24,6 +24,9 @@ diff --git a/resources/views/backend/auth/role/edit.blade.php b/resources/views/backend/auth/role/edit.blade.php old mode 100644 new mode 100755 index 6fbb7aa3..5208fac7 --- a/resources/views/backend/auth/role/edit.blade.php +++ b/resources/views/backend/auth/role/edit.blade.php @@ -24,6 +24,9 @@ diff --git a/resources/views/backend/auth/role/includes/actions.blade.php b/resources/views/backend/auth/role/includes/actions.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/auth/role/includes/children.blade.php b/resources/views/backend/auth/role/includes/children.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/auth/role/includes/no-permissions-message.blade.php b/resources/views/backend/auth/role/includes/no-permissions-message.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/auth/role/includes/row.blade.php b/resources/views/backend/auth/role/includes/row.blade.php old mode 100644 new mode 100755 index a56a822a..ff282945 --- a/resources/views/backend/auth/role/includes/row.blade.php +++ b/resources/views/backend/auth/role/includes/row.blade.php @@ -3,6 +3,12 @@ {{ __('Administrator') }} @elseif ($row->type === \App\Domains\Auth\Models\User::TYPE_USER) {{ __('User') }} + @elseif ($row->type === \App\Domains\Auth\Models\User::TYPE_LECTURER) + {{ __('Lecturer') }} + @elseif ($row->type === \App\Domains\Auth\Models\User::TYPE_TECH_OFFICER) + {{ __('Technical Officer') }} + @elseif ($row->type === \App\Domains\Auth\Models\User::TYPE_MAINTAINER) + {{ __('Maintainer') }} @else N/A @endif diff --git a/resources/views/backend/auth/role/index.blade.php b/resources/views/backend/auth/role/index.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/auth/user/change-password.blade.php b/resources/views/backend/auth/user/change-password.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/auth/user/create.blade.php b/resources/views/backend/auth/user/create.blade.php old mode 100644 new mode 100755 index 883e8dcb..5578101e --- a/resources/views/backend/auth/user/create.blade.php +++ b/resources/views/backend/auth/user/create.blade.php @@ -24,6 +24,9 @@ diff --git a/resources/views/backend/auth/user/deactivated.blade.php b/resources/views/backend/auth/user/deactivated.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/auth/user/deleted.blade.php b/resources/views/backend/auth/user/deleted.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/auth/user/edit.blade.php b/resources/views/backend/auth/user/edit.blade.php old mode 100644 new mode 100755 index b90af2d0..97ed7834 --- a/resources/views/backend/auth/user/edit.blade.php +++ b/resources/views/backend/auth/user/edit.blade.php @@ -25,6 +25,9 @@ diff --git a/resources/views/backend/auth/user/includes/2fa.blade.php b/resources/views/backend/auth/user/includes/2fa.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/auth/user/includes/actions.blade.php b/resources/views/backend/auth/user/includes/actions.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/auth/user/includes/breadcrumb-links.blade.php b/resources/views/backend/auth/user/includes/breadcrumb-links.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/auth/user/includes/row.blade.php b/resources/views/backend/auth/user/includes/row.blade.php old mode 100644 new mode 100755 index 541fa209..dee9f930 --- a/resources/views/backend/auth/user/includes/row.blade.php +++ b/resources/views/backend/auth/user/includes/row.blade.php @@ -1,9 +1,9 @@ - @include('backend.auth.user.includes.type', ['user' => $row]) + {{ $row->name }} - {{ $row->name }} + @include('backend.auth.user.includes.type', ['user' => $row]) diff --git a/resources/views/backend/auth/user/includes/status.blade.php b/resources/views/backend/auth/user/includes/status.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/auth/user/includes/type.blade.php b/resources/views/backend/auth/user/includes/type.blade.php old mode 100644 new mode 100755 index 5d4006b5..4cb7bb1e --- a/resources/views/backend/auth/user/includes/type.blade.php +++ b/resources/views/backend/auth/user/includes/type.blade.php @@ -2,6 +2,12 @@ @lang('Administrator') @elseif ($user->isUser()) @lang('User') +@elseif ($user->isLecturer()) + @lang('Lecturer') +@elseif ($user->isTechOfficer()) + @lang('Technical Officer') +@elseif ($user->isMaintainer()) + @lang('Maintainer') @else @lang('N/A') @endif diff --git a/resources/views/backend/auth/user/includes/verified.blade.php b/resources/views/backend/auth/user/includes/verified.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/auth/user/index.blade.php b/resources/views/backend/auth/user/index.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/auth/user/show.blade.php b/resources/views/backend/auth/user/show.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/component/includes/breadcrumb-links.blade.php b/resources/views/backend/component/includes/breadcrumb-links.blade.php old mode 100644 new mode 100755 index 3f028ccd..885c6112 --- a/resources/views/backend/component/includes/breadcrumb-links.blade.php +++ b/resources/views/backend/component/includes/breadcrumb-links.blade.php @@ -3,18 +3,10 @@ class="c-subheader-nav-link" :href="route('admin.component.items.index')" :text="__('Component Items')" - {{-- permission="admin.access.user.reactivate"--}} > - - - -{{--@if ($logged_in_user->hasAllAccess())--}} -{{-- --}} -{{--@endif--}} diff --git a/resources/views/backend/component/index.blade.php b/resources/views/backend/component/index.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/component/items/create.blade.php b/resources/views/backend/component/items/create.blade.php old mode 100644 new mode 100755 index 174a6742..b72b9c42 --- a/resources/views/backend/component/items/create.blade.php +++ b/resources/views/backend/component/items/create.blade.php @@ -37,7 +37,7 @@
{!! Form::label('component_type_id', 'Category*', ['class' => 'col-md-2 col-form-label']) !!} -
+
{!! Form::select('component_type_id', $types, null, ['class'=>'form-control', 'required'=>true, 'placeholder' => '']) !!} @error('component_type_id') {{ $message }} @@ -92,26 +92,13 @@
- -
- {!! Form::label('instructions', 'Usage Instructions', ['class' => 'col-md-2 col-form-label']) !!} - -
- {!! Form::textarea('instructions', '', ['class'=>'form-control', 'rows'=>3 ]) !!} - @error('instructions') - {{ $message }} - @enderror -
-
- - - +
- {!! Form::label('size', 'Size', ['class' => 'col-sm-2 form-label']) !!} + {!! Form::label('datasheet', 'Datasheet URL', ['class' => 'col-md-2 col-form-label']) !!}
- {!! Form::select('size',['very small'=>'very small', 'small'=> 'small', 'medium'=> 'medium','regular'=>'regular', 'large'=>'large','very large'=> 'very large'] ,'very small', ['class'=>'form-control']) !!} - @error('size') + {!! Form::text('datasheet', '', ['class'=>'form-control', 'rows'=>3 ]) !!} + @error('datasheet') {{ $message }} @enderror
@@ -128,7 +115,7 @@ @enderror
- +
{!! Form::label('price', 'Price (LKR)', ['class' => 'col-md-2 col-form-label']) !!} @@ -141,41 +128,6 @@
- - -
- {!! Form::label('Available?', '', ['class' => 'col-md-2 col-form-label']) !!} - -
- {!!Form::checkbox('isAvailable','', true); !!} - @error('isAvailable') - {{ $message }} - @enderror -
-
- -
- - {!! Form::label('isElectrical', 'Electrical?', ['class' => 'col-md-2 form-check-label']) !!} - -
- {!! Form::checkbox('isElectrical', '1', ['class'=>'form-check-input']) !!} - @error('isElectrical') - {{ $message }} - @enderror -
- - - {!! Form::label('powerRating', 'Power Rating (Watts)', ['class' => 'col-md-2 col-form-label']) !!} - -
- {!! Form::number('powerRating', '', ['class'=>'form-control']) !!} - @error('powerRating') - {{ $message }} - @enderror -
-
-
{!! Form::label('thumb', 'Thumbnail', ['class' => 'col-md-2 col-form-label']) !!} diff --git a/resources/views/backend/component/items/delete.blade.php b/resources/views/backend/component/items/delete.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/component/items/edit-location.blade.php b/resources/views/backend/component/items/edit-location.blade.php new file mode 100755 index 00000000..b6414cf2 --- /dev/null +++ b/resources/views/backend/component/items/edit-location.blade.php @@ -0,0 +1,36 @@ +@extends('backend.layouts.app') + +@section('title', __('Component Locations')) + +@section('breadcrumb-links') + @include('backend.component.includes.breadcrumb-links') +@endsection + +@section('content') +
+ + + Component Locations + + + @if (session('Success')) + + {{ session('Success') }} + + @endif +

Change locations for {{ $componentItem->title }}

+ +
    + @foreach ($locations as $i => $loc) + @include('backend.partials.location-hierarchy-for-edit-location', [ + 'location' => $loc, + 'itemModel' => $componentItem, + ]) + @endforeach +
+
+ Back +
+
+
+@endsection diff --git a/resources/views/backend/component/items/edit.blade.php b/resources/views/backend/component/items/edit.blade.php old mode 100644 new mode 100755 index 01643289..edee6924 --- a/resources/views/backend/component/items/edit.blade.php +++ b/resources/views/backend/component/items/edit.blade.php @@ -38,13 +38,14 @@
{!! Form::label('component_type_id', 'Category*', ['class' => 'col-md-2 col-form-label']) !!} -
+
{!! Form::select('component_type_id', $types, $componentItem->component_type_id, ['class'=>'form-control', 'required'=>true, 'placeholder' => '']) !!} @error('component_type_id') {{ $message }} @enderror
+
@@ -93,26 +94,13 @@
- +
- {!! Form::label('instructions', 'Usage Instructions', ['class' => 'col-md-2 col-form-label']) !!} + {!! Form::label('datasheet', 'Datasheet URL', ['class' => 'col-md-2 col-form-label']) !!}
- {!! Form::textarea('instructions', $componentItem->instructions, ['class'=>'form-control', 'rows'=>3 ]) !!} - @error('instructions') - {{ $message }} - @enderror -
-
- - - -
- {!! Form::label('size', 'Size', ['class' => 'col-sm-2 form-label']) !!} - -
- {!! Form::select('size', ['very small'=>'very small', 'small'=> 'small', 'medium'=> 'medium','regular'=>'regular', 'large'=>'large','very large'=> 'very large'], $componentItem->size, ['class'=>'form-control']) !!} - @error('size') + {!! Form::text('datasheet', $componentItem->datasheet, ['class'=>'form-control', 'rows'=>3 ]) !!} + @error('datasheet') {{ $message }} @enderror
@@ -142,40 +130,6 @@
- -
- {!! Form::label('Available?', '', ['class' => 'col-md-2 col-form-label']) !!} - -
- {!!Form::checkbox('isAvailable',1, ($componentItem->isAvailable)?true:false); !!} - @error('isAvailable') - {{ $message }} - @enderror -
-
- - -
- {!! Form::label('isElectrical', 'Electrical?', ['class' => 'col-md-2 form-check-label']) !!} - -
- {!!Form::checkbox('isElectrical',1, ($componentItem->isElectrical)?true:false); !!} - @error('isElectrical') - {{ $message }} - @enderror -
- - - {!! Form::label('powerRating', 'Power Rating (Watts)', ['class' => 'col-md-2 col-form-label']) !!} - -
- {!! Form::number('powerRating', $componentItem->powerRating, ['class'=>'form-control']) !!} - @error('powerRating') - {{ $message }} - @enderror -
-
-
{!! Form::label('thumb', 'Thumbnail', ['class' => 'col-md-2 col-form-label']) !!} diff --git a/resources/views/backend/component/items/index-table-row.blade.php b/resources/views/backend/component/items/index-table-row.blade.php new file mode 100755 index 00000000..1b566ca2 --- /dev/null +++ b/resources/views/backend/component/items/index-table-row.blade.php @@ -0,0 +1,37 @@ + + {{ $row->inventoryCode() }} + + + + {{ $row->title }} + + + + {{ $row->productCode ?? 'N/A' }}
({{ $row->brand ?? 'N/A' }}) +
+ + + @if ($row->component_type() != null) + + {{ $row->component_type['title'] }} + + @endif + + + +
+
+ + + + + + + +
+
+
diff --git a/resources/views/backend/component/items/index.blade.php b/resources/views/backend/component/items/index.blade.php old mode 100644 new mode 100755 index 43436633..3a1254b0 --- a/resources/views/backend/component/items/index.blade.php +++ b/resources/views/backend/component/items/index.blade.php @@ -13,77 +13,22 @@ Component - @if ($logged_in_user->hasAllAccess()) + @if ($logged_in_user->hasInventoryAccess()) - + + @endif @if (session('Success')) -
+ {{ session('Success') }} - -
+ @endif -
- - - - - - {{-- --}} - - - - - @foreach($components as $cm) - - - - - - - - - - - - @endforeach -
TitleProduct Code
and Brand
CategoryPrice (LKR)Size 
{{ $cm->title }}{{ $cm->productCode ?? 'N/A' }} ({{ $cm->brand ?? 'N/A' }}) - @if($cm->component_type() != null) - - {{ $cm->component_type['title'] }} - - @endif - {{ $cm->size }} -
-
- - - - - - - -
-
-
- - {{ $components->links() }} -
+
diff --git a/resources/views/backend/component/items/show.blade.php b/resources/views/backend/component/items/show.blade.php old mode 100644 new mode 100755 index 59465def..8ddf3390 --- a/resources/views/backend/component/items/show.blade.php +++ b/resources/views/backend/component/items/show.blade.php @@ -23,8 +23,11 @@ + + @@ -35,6 +38,21 @@ class="btn btn-danger btn-xs">Code (to be finalized) {{ $componentItem->inventoryCode() }} + @if(count($locations_array) > 0) + + Locations + + @foreach($locations_array as $eachLocation) + {{ $eachLocation }}
+ @endforeach + + + @else + + Location + Not Available + + @endif Type @@ -64,14 +82,8 @@ class="btn btn-danger btn-xs"> - Quantity - {{ $componentItem->quantity }} - - - - - Size - {{ $componentItem->size }} + Quantity + {{ $componentItem->quantity }} @@ -80,40 +92,8 @@ class="btn btn-danger btn-xs">{!! str_replace("\n", "
", $componentItem->description) !!} - Usage Instructions - {!! str_replace("\n", "
", $componentItem->instructions) !!} - - - {{-- !have to be changed --}} - Is It Available ? - - @if($componentItem->isAvailable=='1') - YES - @else - NO - @endif - - - - Is It Electrical? ? - - @if($componentItem->isElectrical=='1') - YES - @else - NO - @endif - - - - - Power Rating - - @if( $componentItem->powerRating != null ) - {{ $componentItem->powerRating." W"}} - @else - [Not Available] - @endif - + Datasheet + {{ $componentItem->datasheet }} diff --git a/resources/views/backend/component/types/create.blade.php b/resources/views/backend/component/types/create.blade.php old mode 100644 new mode 100755 index e0f90caf..576921e7 --- a/resources/views/backend/component/types/create.blade.php +++ b/resources/views/backend/component/types/create.blade.php @@ -51,7 +51,7 @@
{!! Form::label('parent_id', 'Parent Category', ['class' => 'col-md-2 col-form-label']) !!} -
+
{!! Form::select('parent_id', $types, null, ['class'=>'form-control', 'required'=>false, 'placeholder' => '']) !!} @error('parent_id') {{ $message }} @@ -61,10 +61,10 @@
- {!! Form::label('description', 'Description*', ['class' => 'col-md-2 col-form-label']) !!} + {!! Form::label('description', 'Description', ['class' => 'col-md-2 col-form-label']) !!}
- {!! Form::textarea('description', '', ['class'=>'form-control', 'rows'=>3, 'required'=>true ]) !!} + {!! Form::textarea('description', '', ['class'=>'form-control', 'rows'=>3, 'required'=>false ]) !!}
@error('description') diff --git a/resources/views/backend/component/types/delete.blade.php b/resources/views/backend/component/types/delete.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/component/types/edit.blade.php b/resources/views/backend/component/types/edit.blade.php old mode 100644 new mode 100755 index 034e43ef..299fa049 --- a/resources/views/backend/component/types/edit.blade.php +++ b/resources/views/backend/component/types/edit.blade.php @@ -52,7 +52,7 @@
{!! Form::label('parent_id', 'Parent Category', ['class' => 'col-md-2 col-form-label']) !!} -
+
{!! Form::select('parent_id', $types, $componentType->parent_id, ['class'=>'form-control', 'required'=>false, 'placeholder' => '']) !!} @error('parent_id') {{ $message }} @@ -62,10 +62,10 @@
- {!! Form::label('description', 'Description*', ['class' => 'col-md-2 col-form-label']) !!} + {!! Form::label('description', 'Description', ['class' => 'col-md-2 col-form-label']) !!}
- {!! Form::textarea('description', $componentType->description, ['class'=>'form-control', 'rows'=>3, 'required'=>true ]) !!} + {!! Form::textarea('description', $componentType->description, ['class'=>'form-control', 'rows'=>3, 'required'=>false ]) !!}
@error('description') diff --git a/resources/views/backend/component/types/index-table-row.blade.php b/resources/views/backend/component/types/index-table-row.blade.php new file mode 100755 index 00000000..68ad7d45 --- /dev/null +++ b/resources/views/backend/component/types/index-table-row.blade.php @@ -0,0 +1,42 @@ + + {{ $row->inventoryCode() }} + + + + {{ $row->title }} + + + + @if ($row->parent()->first() !== null) + + {{ $row->parent()->first()->title }} + + @else + N/A + @endif + + + + @if ($row->description == '') + N/A + @else + {{ $row->description }} + @endif + + + +
+
+ + + + + + + +
+
+
diff --git a/resources/views/backend/component/types/index.blade.php b/resources/views/backend/component/types/index.blade.php old mode 100644 new mode 100755 index 6b11afa8..e6702700 --- a/resources/views/backend/component/types/index.blade.php +++ b/resources/views/backend/component/types/index.blade.php @@ -3,85 +3,34 @@ @section('title', __('Component Types')) @section('breadcrumb-links') -@include('backend.component.includes.breadcrumb-links') + @include('backend.component.includes.breadcrumb-links') @endsection @section('content') -
- - - Component Types - - - {{-- @if ($logged_in_user->hasAllAccess())--}} - - - - {{-- @endif--}} - - - - @if (session('Success')) -
- {{ session('Success') }} - -
+
+ + + Component Types + + + @if ($logged_in_user->hasInventoryAccess()) + + + + @endif -
- - - - - {{-- --}} - - - + - @foreach($componentTypes as $type) - - - - {{-- --}} - - + - - @endforeach -
TitleParent CategorySubtitleDescription 
{{ $type->title }} - @if( $type->parent() !== null) - - {{ $type->parent()->title }} - - @else - N/A - @endif - {{ $type->subtitle ?? 'N/A' }}{{ $type->description }} -
-
- - + @if (session('Success')) + + {{ session('Success') }} + + @endif - - - - -
-
-
- {{ $componentTypes->links() }} -
- -
-
+
+
+
@endsection diff --git a/resources/views/backend/component/types/show.blade.php b/resources/views/backend/component/types/show.blade.php old mode 100644 new mode 100755 index c2284cfa..cc02b234 --- a/resources/views/backend/component/types/show.blade.php +++ b/resources/views/backend/component/types/show.blade.php @@ -10,7 +10,7 @@
- Component Types : Show {{ $componentType->title }} + Component Types : Show {{ $componentType->title }} @@ -20,12 +20,11 @@
@@ -39,19 +38,47 @@ class="btn btn-danger btn-xs"> Parent Category - @if( $componentType->parent() !== null) - - {{ $componentType->parent()->title }} + @php + $level1 = $componentType->parent()->first(); + @endphp + @if ($level1 !== null) + + @php + $level2 = $level1->parent()->first(); + @endphp + + @if ($level2 !== null) + + @php + $level3 = $level2->parent()->first(); + @endphp + + @if ($level3 !== null) + + {{ $level3->title }} + {{ ' > ' }} + @endif + + {{ $level2->title }} + {{ ' > ' }} + @endif + + + {{ $level1->title }} @else N/A @endif - - Subtitle - {{ $componentType->subtitle }} - + + @if ($componentType->subtitle != '') + + Subtitle + {{ $componentType->subtitle }} + + @endif + Description {{ $componentType->description }} @@ -59,9 +86,9 @@ class="btn btn-danger btn-xs"> Thumbnail - @if( $componentType->thumb != null ) + @if ($componentType->thumb != null) {{ $componentType->title }} + class="img img-thumbnail"> @else [Not Available] @endif diff --git a/resources/views/backend/consumable/includes/breadcrumb-links.blade.php b/resources/views/backend/consumable/includes/breadcrumb-links.blade.php new file mode 100755 index 00000000..abef26de --- /dev/null +++ b/resources/views/backend/consumable/includes/breadcrumb-links.blade.php @@ -0,0 +1,16 @@ + + + + + +{{--@if ($logged_in_user->hasAllAccess())--}} +{{-- --}} +{{--@endif--}} diff --git a/resources/views/backend/consumable/index.blade.php b/resources/views/backend/consumable/index.blade.php new file mode 100755 index 00000000..03066f9f --- /dev/null +++ b/resources/views/backend/consumable/index.blade.php @@ -0,0 +1,23 @@ +@extends('backend.layouts.app') + +@section('title', __('equipment')) + +@section('breadcrumb-links') + @include('backend.equipment.includes.breadcrumb-links') +@endsection + +@section('content') +
+ + + Consumables + + + + Items +
+ Types +
+
+
+@endsection diff --git a/resources/views/backend/consumable/items/create.blade.php b/resources/views/backend/consumable/items/create.blade.php new file mode 100755 index 00000000..9d9b485f --- /dev/null +++ b/resources/views/backend/consumable/items/create.blade.php @@ -0,0 +1,137 @@ +@extends('backend.layouts.app') + +@section('title', __('Consumable')) + +@section('breadcrumb-links') + @include('backend.consumable.includes.breadcrumb-links') +@endsection + +@section('content') +
+ {!! Form::open([ + 'url' => route('admin.consumable.items.store'), + 'method' => 'post', + 'class' => 'container', + 'files' => true, + 'enctype' => 'multipart/form-data', + ]) !!} + + + + Consumable : Create + + + + +
+ {!! Form::label('title', 'Title*', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::text('title', '', ['class' => 'form-control', 'required' => true]) !!} + @error('title') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('consumable_type_id', 'Category*', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::select('consumable_type_id', $types, null, [ + 'class' => 'form-control', + 'required' => true, + 'placeholder' => '', + ]) !!} + @error('consumable_type_id') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('specifications', 'Specifications', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::textarea('specifications', '', ['class' => 'form-control', 'rows' => 3]) !!} + @error('specifications') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('quantity', 'Quantity', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::number('quantity', '', ['class' => 'form-control']) !!} + @error('quantity') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('price', 'Price (LKR)', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::number('price', '', ['class' => 'form-control', 'step' => '0.01']) !!} + @error('price') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('formFactor', 'Form Factor', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::text('formFactor', '', ['class' => 'form-control']) !!} + @error('formFactor') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('datasheetURL', 'Datasheet URL', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::text('datasheetURL', '', ['class' => 'form-control']) !!} + @error('datasheetURL') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('thumb', 'Thumbnail', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::file('thumb', ['accept' => '.jpeg,.png,.jpg,.gif,.svg']) !!} (Max: 2MB, use square + image) + + @error('thumb') + {{ $message }} + @enderror +
+
+ +
+ + + {!! Form::submit('Create', ['class' => 'btn btn-primary float-right']) !!} + + +
+ + {!! Form::close() !!} +
+@endsection diff --git a/resources/views/backend/consumable/items/delete.blade.php b/resources/views/backend/consumable/items/delete.blade.php new file mode 100755 index 00000000..eed7b1b1 --- /dev/null +++ b/resources/views/backend/consumable/items/delete.blade.php @@ -0,0 +1,32 @@ +@extends('backend.layouts.app') + +@section('title', __('Consumable')) + +@section('breadcrumb-links') + @include('backend.consumable.includes.breadcrumb-links') +@endsection + +@section('content') +
+ + + Consumable : Delete | {{ $consumableItem->title }} + + + +

Are you sure you want to delete + {{ $consumableItem->title }} ? +

+ +
+ {!! Form::open(['url' => route('admin.consumable.items.destroy', compact('consumableItem') ), 'method' => 'delete', 'class' => 'container']) !!} + + Back + {!! Form::submit('Delete', ['class'=>'btn btn-danger']) !!} + + {!! Form::close() !!} +
+
+
+
+@endsection diff --git a/resources/views/backend/consumable/items/edit-location.blade.php b/resources/views/backend/consumable/items/edit-location.blade.php new file mode 100755 index 00000000..e9d0abf9 --- /dev/null +++ b/resources/views/backend/consumable/items/edit-location.blade.php @@ -0,0 +1,36 @@ +@extends('backend.layouts.app') + +@section('title', __('Consumable Locations')) + +@section('breadcrumb-links') + @include('backend.consumable.includes.breadcrumb-links') +@endsection + +@section('content') +
+ + + Consumable Locations + + + @if (session('Success')) + + {{ session('Success') }} + + @endif +

Change locations for {{ $consumableItem->title }}

+ +
    + @foreach ($locations as $i => $loc) + @include('backend.partials.location-hierarchy-for-edit-location', [ + 'location' => $loc, + 'itemModel' => $consumableItem, + ]) + @endforeach +
+
+ Back +
+
+
+@endsection diff --git a/resources/views/backend/consumable/items/edit.blade.php b/resources/views/backend/consumable/items/edit.blade.php new file mode 100755 index 00000000..ceec76bb --- /dev/null +++ b/resources/views/backend/consumable/items/edit.blade.php @@ -0,0 +1,135 @@ +@extends('backend.layouts.app') + +@section('title', __('Consumable')) + +@section('breadcrumb-links') + @include('backend.consumable.includes.breadcrumb-links') +@endsection + +@section('content') +
+ {!! Form::open([ + 'url' => route('admin.consumable.items.update', compact('consumableItem')), + 'method' => 'put', + 'class' => 'container', + 'files' => true, + 'enctype' => 'multipart/form-data', + ]) !!} + + + + Consumable : Edit | {{ $consumableItem->title }} + + + + +
+ {!! Form::label('title', 'Title*', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::text('title', $consumableItem->title, ['class' => 'form-control', 'required' => true]) !!} + @error('title') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('consumable_type_id', 'Category*', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::select('consumable_type_id', $types, $consumableItem->consumable_type_id, [ + 'class' => 'form-control', + 'required' => true, + 'placeholder' => '', + ]) !!} + @error('consumable_type_id') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('specifications', 'Specifications', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::textarea('specifications', $consumableItem->specifications, ['class' => 'form-control', 'rows' => 3]) !!} + @error('specifications') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('quantity', 'Quantity', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::number('quantity', $consumableItem->quantity, ['class' => 'form-control']) !!} + @error('quantity') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('price', 'Price (LKR)', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::number('price', $consumableItem->price, ['class' => 'form-control', 'step' => '0.01']) !!} + @error('price') + {{ $message }} + @enderror +
+
+ + {{-- FormFactor --}} +
+ {!! Form::label('formFactor', 'Form factor', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::text('formFactor', $consumableItem->formFactor, ['class' => 'form-control']) !!} + @error('formFactor') + {{ $message }} + @enderror +
+
+ + {{-- datasheetURL --}} +
+ {!! Form::label('datasheetURL', 'Datasheet URL', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::text('datasheetURL', $consumableItem->datasheetURL, ['class' => 'form-control']) !!} + @error('datasheetURL') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('thumb', 'Thumbnail', ['class' => 'col-md-2 col-form-label']) !!} + +
+ + {!! Form::file('thumb', ['accept' => '.jpeg,.png,.jpg,.gif,.svg']) !!} (Max: 2MB, use square + image) + @error('thumb') + {{ $message }} + @enderror +
+
+ +
+ + {!! Form::submit('Update', ['class' => 'btn btn-primary float-right']) !!} + + +
+ {!! Form::close() !!} +
+@endsection diff --git a/resources/views/backend/consumable/items/index-table-row.blade.php b/resources/views/backend/consumable/items/index-table-row.blade.php new file mode 100755 index 00000000..62e74c1c --- /dev/null +++ b/resources/views/backend/consumable/items/index-table-row.blade.php @@ -0,0 +1,49 @@ + + {{ $row->inventoryCode() }} + + + + {{ $row->title }} + + + + @if($row->consumable_type() != null) + + {{ $row->consumable_type['title'] }} + + @endif + + + + @if ($row->formFactor == '') + N/A + @else + {{ $row->formFactor }} + @endif + + + + {{ $row->quantity }} + + + +
+
+ + + + + + + + + +
+
+
\ No newline at end of file diff --git a/resources/views/backend/consumable/items/index.blade.php b/resources/views/backend/consumable/items/index.blade.php new file mode 100755 index 00000000..91029439 --- /dev/null +++ b/resources/views/backend/consumable/items/index.blade.php @@ -0,0 +1,37 @@ +@extends('backend.layouts.app') + +@section('title', __('Consumable')) + +@section('breadcrumb-links') + @include('backend.consumable.includes.breadcrumb-links') +@endsection + +@section('content') +
+ + + Consumable + + + @if ($logged_in_user->hasInventoryAccess()) + + + + + + + @endif + + + + @if (session('Success')) + + {{ session('Success') }} + + @endif + + + + +
+@endsection diff --git a/resources/views/backend/consumable/items/show.blade.php b/resources/views/backend/consumable/items/show.blade.php new file mode 100755 index 00000000..1e6eb96c --- /dev/null +++ b/resources/views/backend/consumable/items/show.blade.php @@ -0,0 +1,132 @@ +@extends('backend.layouts.app') + +@section('title', __('Consumable')) + +@section('breadcrumb-links') + @include('backend.consumable.includes.breadcrumb-links') +@endsection + +@section('content') +
+ + + Consumable : Show | {{ $consumableItem->title }} + + + +
+
+

{{ $consumableItem->title }}

+
+
+
+ + + + + + +
+
+
+ + + + + + + @if (count($locations_array) > 0) + + + + + @else + + + + + @endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Code (to be finalized){{ $consumableItem->inventoryCode() }}
Locations + @foreach ($locations_array as $eachLocation) + {{ $eachLocation }}
+ @endforeach +
LocationNot Available
Type + @if ($consumableItem->consumable_type != null) + + {{ $consumableItem->consumable_type['title'] }} + + @endif +
Price + @if ($consumableItem->price != null) + Rs. {{ $consumableItem->price }} + @else + N/A + @endif +
Quantity{{ $consumableItem->quantity }} +
Form factor{{ $consumableItem->formFactor }} +
Specification{!! str_replace("\n", '
', $consumableItem->specifications) !!}
Thumbnail + @if ($consumableItem->thumbURL() != null) + {{ $consumableItem->title }} + @else + [Not Available] + @endif +
+
+
+
+@endsection diff --git a/resources/views/backend/consumable/types/create.blade.php b/resources/views/backend/consumable/types/create.blade.php new file mode 100755 index 00000000..02dc0306 --- /dev/null +++ b/resources/views/backend/consumable/types/create.blade.php @@ -0,0 +1,98 @@ +@extends('backend.layouts.app') + +@section('title', __('Consumable Types')) + +@section('breadcrumb-links') + @include('backend.consumable.includes.breadcrumb-links') +@endsection + +@section('content') +
+ {!! Form::open(['url' => route('admin.consumable.types.store'), + 'method' => 'post', + 'class' => 'container', + 'files'=>true, + 'enctype'=>'multipart/form-data' + ]) !!} + + + + Consumable Types : Create + + + + +
+ {!! Form::label('title', 'Title of the type*', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::text('title', '', ['class'=>'form-control', 'required'=>true ]) !!} +
+ + @error('title') + {{ $message }} + @enderror +
+ + +
+ {!! Form::label('subtitle', 'Subtitle of the type', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::text('subtitle', '', ['class'=>'form-control']) !!} +
+ + @error('subtitle') + {{ $message }} + @enderror +
+ + +
+ {!! Form::label('parent_id', 'Parent Category', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::select('parent_id', $types, null, ['class'=>'form-control', 'required'=>false, 'placeholder' => '']) !!} + @error('parent_id') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('description', 'Description*', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::textarea('description', '', ['class'=>'form-control', 'rows'=>3, 'required'=>true ]) !!} +
+ + @error('description') + {{ $message }} + @enderror +
+ + +
+ {!! Form::label('thumb', 'Thumbnail', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::file('thumb', ["accept"=>".jpeg,.png,.jpg,.gif,.svg"]); !!} (Max: 2MB, use square + image) + @error('thumb') + {{ $message }} + @enderror +
+
+ +
+ + + {!! Form::submit('Create', ['class'=>'btn btn-primary float-right']) !!} + + +
+ + {!! Form::close() !!} +
+@endsection diff --git a/resources/views/backend/consumable/types/delete.blade.php b/resources/views/backend/consumable/types/delete.blade.php new file mode 100755 index 00000000..1895ec54 --- /dev/null +++ b/resources/views/backend/consumable/types/delete.blade.php @@ -0,0 +1,32 @@ +@extends('backend.layouts.app') + +@section('title', __('Consumable Types')) + +@section('breadcrumb-links') + @include('backend.consumable.includes.breadcrumb-links') +@endsection + +@section('content') +
+ + + Consumable Types : Delete {{ $consumableType->title }} + + + +

Are you sure you want to delete + {{ $consumableType->title }} ? +

+ +
+ {!! Form::open(['url' => route('admin.consumable.types.destroy', compact('consumableType') ), 'method' => 'delete', 'class' => 'container']) !!} + + Back + {!! Form::submit('Delete', ['class'=>'btn btn-danger']) !!} + + {!! Form::close() !!} +
+
+
+
+@endsection diff --git a/resources/views/backend/consumable/types/edit.blade.php b/resources/views/backend/consumable/types/edit.blade.php new file mode 100755 index 00000000..2b48e371 --- /dev/null +++ b/resources/views/backend/consumable/types/edit.blade.php @@ -0,0 +1,99 @@ +@extends('backend.layouts.app') + +@section('title', __('Consumable Types')) + +@section('breadcrumb-links') + @include('backend.consumable.includes.breadcrumb-links') +@endsection + +@section('content') +
+ {!! Form::open(['url' => route('admin.consumable.types.update', + compact('consumableType')), + 'method' => 'put', + 'class' => 'container', + 'files'=>true, + 'enctype'=>'multipart/form-data' + ]) !!} + + + + Consumable Types : Edit {{ $consumableType->title }} + + + + +
+ {!! Form::label('title', 'Title of the type*', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::text('title', $consumableType->title, ['class'=>'form-control', 'required'=>true ]) !!} +
+ + @error('title') + {{ $message }} + @enderror +
+ + +
+ {!! Form::label('subtitle', 'Subtitle of the type', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::text('subtitle', $consumableType->subtitle, ['class'=>'form-control']) !!} +
+ + @error('subtitle') + {{ $message }} + @enderror +
+ + +
+ {!! Form::label('parent_id', 'Parent Category', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::select('parent_id', $types, $consumableType->parent_id, ['class'=>'form-control', 'required'=>false, 'placeholder' => '']) !!} + @error('parent_id') + {{ $message }} + @enderror +
+
+ + +
+ {!! Form::label('description', 'Description*', ['class' => 'col-md-2 col-form-label']) !!} + +
+ {!! Form::textarea('description', $consumableType->description, ['class'=>'form-control', 'rows'=>3, 'required'=>true ]) !!} +
+ + @error('description') + {{ $message }} + @enderror +
+ + +
+ {!! Form::label('thumb', 'Thumbnail', ['class' => 'col-md-2 col-form-label']) !!} + +
+ + {!! Form::file('thumb', ["accept"=>".jpeg,.png,.jpg,.gif,.svg"]); !!} (Max: 2MB, use square + image) + @error('thumb') + {{ $message }} + @enderror +
+
+
+ + + {!! Form::submit('Save', ['class'=>'btn btn-primary float-right']) !!} + + +
+ + {!! Form::close() !!} +
+@endsection diff --git a/resources/views/backend/consumable/types/index-table-row.blade.php b/resources/views/backend/consumable/types/index-table-row.blade.php new file mode 100755 index 00000000..24a626c5 --- /dev/null +++ b/resources/views/backend/consumable/types/index-table-row.blade.php @@ -0,0 +1,38 @@ + + {{ $row->inventoryCode() }} + + + + {{ $row->title }} + + + + @if ($row->parent()->first() !== null) + + {{ $row->parent()->first()->title }} + + @else + N/A + @endif + + + + {{ $row->description }} + + + +
+
+ + + + + + + +
+
+
diff --git a/resources/views/backend/consumable/types/index.blade.php b/resources/views/backend/consumable/types/index.blade.php new file mode 100755 index 00000000..10cbc22e --- /dev/null +++ b/resources/views/backend/consumable/types/index.blade.php @@ -0,0 +1,36 @@ +@extends('backend.layouts.app') + +@section('title', __('Consumable Types')) + +@section('breadcrumb-links') + @include('backend.consumable.includes.breadcrumb-links') +@endsection + +@section('content') +
+ + + Consumable Types + + + @if ($logged_in_user->hasInventoryAccess()) + + + + + @endif + + + + @if (session('Success')) + + {{ session('Success') }} + + @endif + + + + + +
+@endsection diff --git a/resources/views/backend/consumable/types/show.blade.php b/resources/views/backend/consumable/types/show.blade.php new file mode 100755 index 00000000..7ab0f5c4 --- /dev/null +++ b/resources/views/backend/consumable/types/show.blade.php @@ -0,0 +1,97 @@ +@extends('backend.layouts.app') + +@section('title', __('Component Types')) + +@section('breadcrumb-links') + @include('backend.consumable.includes.breadcrumb-links') +@endsection + +@section('content') +
+ + + Consumable Types : Show {{ $consumableType->title }} + + + +
+
+

{{ $consumableType->title }}

+
+
+
+ + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + +
Code (to be finalized){{ $consumableType->inventoryCode() }}
Parent Category + @php + $level1 = $consumableType->parent()->first(); + @endphp + @if ($level1 !== null) + + @php + $level2 = $level1->parent()->first(); + @endphp + + @if ($level2 !== null) + + @php + $level3 = $level2->parent()->first(); + @endphp + + @if ($level3 !== null) + + {{ $level3->title }} + {{ ' > ' }} + @endif + + {{ $level2->title }} + {{ ' > ' }} + @endif + + + {{ $level1->title }} + + @else + N/A + @endif +
Subtitle{{ $consumableType->subtitle }}
Description{{ $consumableType->description }}
Thumbnail + @if ($consumableType->thumb != null && $consumableType->thumb != '') + {{ $consumableType->title }} + @else + [Not Available] + @endif +
+
+
+
+@endsection diff --git a/resources/views/backend/dashboard.blade.php b/resources/views/backend/dashboard.blade.php old mode 100644 new mode 100755 index 41cc02fa..a12622a8 --- a/resources/views/backend/dashboard.blade.php +++ b/resources/views/backend/dashboard.blade.php @@ -40,6 +40,12 @@ color: #FFF; } + .card-counter.custom { + background-color: #c55d88; + color: #FFF; + } + + .card-counter i { font-size: 5em; opacity: 0.2; @@ -93,6 +99,15 @@
+ +
@if ($logged_in_user->hasAllAccess()) @@ -101,17 +116,41 @@ {{ $userCount }} Users
- @if ($logged_in_user->hasAllAccess()) @endif + @if ($logged_in_user->hasAllAccess()) + @endif +
+ + +
+ +
diff --git a/resources/views/backend/equipment/includes/breadcrumb-links.blade.php b/resources/views/backend/equipment/includes/breadcrumb-links.blade.php old mode 100644 new mode 100755 index 96e0b6b2..73585e88 --- a/resources/views/backend/equipment/includes/breadcrumb-links.blade.php +++ b/resources/views/backend/equipment/includes/breadcrumb-links.blade.php @@ -3,14 +3,12 @@ class="c-subheader-nav-link" :href="route('admin.equipment.items.index')" :text="__('Equipment Items')" - {{-- permission="admin.access.user.reactivate"--}} > diff --git a/resources/views/backend/equipment/index.blade.php b/resources/views/backend/equipment/index.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/equipment/items/create.blade.php b/resources/views/backend/equipment/items/create.blade.php old mode 100644 new mode 100755 index 70525869..e740a7bc --- a/resources/views/backend/equipment/items/create.blade.php +++ b/resources/views/backend/equipment/items/create.blade.php @@ -15,7 +15,7 @@ 'enctype'=>'multipart/form-data' ]) !!} - + Equipment : Create @@ -44,7 +44,17 @@ @enderror
- +{{-- --}} +{{--
--}} +{{-- {!! Form::label('location_label', 'Location*', ['class' => 'col-md-2 col-form-label']) !!}--}} + +{{--
--}} +{{-- {!! Form::select('location', $locations, null, ['class'=>'form-control', 'required'=>true, 'placeholder' => '']) !!}--}} +{{-- @error('location')--}} +{{-- {{ $message }}--}} +{{-- @enderror--}} +{{--
--}} +{{--
--}}
diff --git a/resources/views/backend/equipment/items/delete.blade.php b/resources/views/backend/equipment/items/delete.blade.php old mode 100644 new mode 100755 index 96ab0b05..2834453c --- a/resources/views/backend/equipment/items/delete.blade.php +++ b/resources/views/backend/equipment/items/delete.blade.php @@ -1,6 +1,6 @@ @extends('backend.layouts.app') -@section('title', __('Equipment')) +@section('title', __('Equipment')) @section('breadcrumb-links') @include('backend.equipment.includes.breadcrumb-links') diff --git a/resources/views/backend/equipment/items/edit-location.blade.php b/resources/views/backend/equipment/items/edit-location.blade.php new file mode 100755 index 00000000..3519c01d --- /dev/null +++ b/resources/views/backend/equipment/items/edit-location.blade.php @@ -0,0 +1,36 @@ +@extends('backend.layouts.app') + +@section('title', __('Equipment Locations')) + +@section('breadcrumb-links') + @include('backend.equipment.includes.breadcrumb-links') +@endsection + +@section('content') +
+ + + Equipment Locations + + + @if (session('Success')) + + {{ session('Success') }} + + @endif +

Change locations for {{ $equipmentItem->title }}

+ +
    + @foreach ($locations as $i => $loc) + @include('backend.partials.location-hierarchy-for-edit-location', [ + 'location' => $loc, + 'itemModel' => $equipmentItem, + ]) + @endforeach +
+
+ Back +
+
+
+@endsection diff --git a/resources/views/backend/equipment/items/edit.blade.php b/resources/views/backend/equipment/items/edit.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/equipment/items/index-table-row.blade.php b/resources/views/backend/equipment/items/index-table-row.blade.php new file mode 100755 index 00000000..c6f39b63 --- /dev/null +++ b/resources/views/backend/equipment/items/index-table-row.blade.php @@ -0,0 +1,59 @@ + + {{$row->inventoryCode() }} + + + + {{ $row->title }} + + + + {{ $row->productCode ?? 'N/A' }}
({{ $row->brand ?? 'N/A' }}) +
+ + + {{ $row->quantity }} + + + + @if($row->equipment_type() != null) + + {{ $row->equipment_type['title'] }} + + @endif + + + + {{ $row->price }} + + +{{----}} +{{-- {{ $row->width }} x {{ $row->height }} x {{ $row->length }}--}} +{{----}} + +{{----}} +{{-- {{ $row->weight }}--}} +{{----}} + + +
+
+ + + + + + + + + +
+
+
+ + + diff --git a/resources/views/backend/equipment/items/index.blade.php b/resources/views/backend/equipment/items/index.blade.php old mode 100644 new mode 100755 index abcc70c3..8b98d630 --- a/resources/views/backend/equipment/items/index.blade.php +++ b/resources/views/backend/equipment/items/index.blade.php @@ -13,81 +13,24 @@ Equipment - @if ($logged_in_user->hasAllAccess()) + @if ($logged_in_user->hasInventoryAccess()) - + + @endif @if (session('Success')) -
+ {{ session('Success') }} - -
+ @endif -
- - - - - - - - - - - - - @foreach($equipment as $eq) - - - - - - - - - - - - - @endforeach -
TitleProduct Code
and Brand
QuantityCategoryPrice (LKR)Dimensions(cm)
W x L x H
Weight (g) 
{{ $eq->title }}{{ $eq->productCode ?? 'N/A' }} ({{ $eq->brand ?? 'N/A' }}){{ $eq->quantity }} - @if($eq->equipment_type() != null) - - {{ $eq->equipment_type['title'] }} - - @endif - {{ $eq->price }}{{ $eq->width }} x {{ $eq->height }} x {{ $eq->length }}{{ $eq->weight }} -
-
- - - - - - - -
-
-
- - {{ $equipment->links() }} -
+
+
@endsection diff --git a/resources/views/backend/equipment/items/show.blade.php b/resources/views/backend/equipment/items/show.blade.php old mode 100644 new mode 100755 index 37e20bb8..8ca8714d --- a/resources/views/backend/equipment/items/show.blade.php +++ b/resources/views/backend/equipment/items/show.blade.php @@ -6,7 +6,7 @@ @include('backend.equipment.includes.breadcrumb-links') @endsection -@section('content') +@section('content')
@@ -23,8 +23,11 @@ + +
@@ -35,6 +38,23 @@ class="btn btn-danger btn-xs">Code (to be finalized) {{ $equipmentItem->inventoryCode() }} + + @if(count($locations_array) > 0) + + Locations + + @foreach($locations_array as $eachLocation) + {{ $eachLocation }}
+ @endforeach + + + @else + + Location + Not Available + + @endif + Type diff --git a/resources/views/backend/equipment/types/create.blade.php b/resources/views/backend/equipment/types/create.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/equipment/types/delete.blade.php b/resources/views/backend/equipment/types/delete.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/equipment/types/edit.blade.php b/resources/views/backend/equipment/types/edit.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/equipment/types/index-table-row.blade.php b/resources/views/backend/equipment/types/index-table-row.blade.php new file mode 100755 index 00000000..049c912a --- /dev/null +++ b/resources/views/backend/equipment/types/index-table-row.blade.php @@ -0,0 +1,39 @@ + + {{ $row->inventoryCode() }} + + + + {{ $row->title }} + + + + @if( $row->parent_id() != null) + + {{ $row->parent()->first()->title }} + + @else + N/A + @endif + + + + {{ $row->description }} + + + +
+
+ + + + + + + +
+
+
\ No newline at end of file diff --git a/resources/views/backend/equipment/types/index.blade.php b/resources/views/backend/equipment/types/index.blade.php old mode 100644 new mode 100755 index fc6756db..db2bcd73 --- a/resources/views/backend/equipment/types/index.blade.php +++ b/resources/views/backend/equipment/types/index.blade.php @@ -13,74 +13,23 @@ Equipment Types - {{-- @if ($logged_in_user->hasAllAccess())--}} - - - - {{-- @endif--}} + @if ($logged_in_user->hasInventoryAccess()) + + + + + @endif @if (session('Success')) -
+ {{ session('Success') }} - -
+ @endif -
- - - - - {{----}} - - - - - @foreach($equipmentTypes as $equipmentType) - - - - {{-- --}} - - + - - @endforeach -
TitleParent CategorySubtitleDescription 
{{ $equipmentType->title }} - @if( $equipmentType->parent() !== null) - - {{ $equipmentType->parent()->title }} - - @else - N/A - @endif - {{ $equipmentType->subtitle ?? 'N/A' }}{{ $equipmentType->description }} -
-
- - - - - - - -
-
-
- {{ $equipmentTypes->links() }} -
diff --git a/resources/views/backend/equipment/types/show.blade.php b/resources/views/backend/equipment/types/show.blade.php old mode 100644 new mode 100755 index dc15b373..c150cd47 --- a/resources/views/backend/equipment/types/show.blade.php +++ b/resources/views/backend/equipment/types/show.blade.php @@ -24,7 +24,7 @@ class="btn btn-info btn-xs">
@@ -39,9 +39,9 @@ class="btn btn-danger btn-xs"> Parent Category - @if( $equipmentType->parent() !== null) - - {{ $equipmentType->parent()->title }} + @if( $equipmentType->parent_id() !== null) + + {{ $equipmentType->parent()->first()->title }} @else N/A diff --git a/resources/views/backend/includes/footer.blade.php b/resources/views/backend/includes/footer.blade.php old mode 100644 new mode 100755 diff --git a/resources/views/backend/includes/header.blade.php b/resources/views/backend/includes/header.blade.php old mode 100644 new mode 100755 index e666041b..e3d4042e --- a/resources/views/backend/includes/header.blade.php +++ b/resources/views/backend/includes/header.blade.php @@ -3,12 +3,6 @@ - - - - - - @@ -49,9 +43,9 @@ class="c-header-nav-link dropdown-toggle" - + - User Dashboard + User Overview diff --git a/resources/views/backend/includes/partials/breadcrumbs.blade.php b/resources/views/backend/includes/partials/breadcrumbs.blade.php old mode 100644 new mode 100755 index 1111207e..aa995af0 --- a/resources/views/backend/includes/partials/breadcrumbs.blade.php +++ b/resources/views/backend/includes/partials/breadcrumbs.blade.php @@ -1,5 +1,5 @@ @if (Breadcrumbs::has()) -