Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- use App\Exceptions\ApiExceptions\SystemException;
- use App\Model\Category;
- use App\Model\City;
- use App\Model\Company;
- use App\Model\CompanyService;
- use App\Model\CompanyTimetable;
- use App\Model\Image;
- use App\Model\Location;
- use App\Model\Provider;
- use App\Model\ProviderService;
- use App\Model\Reservation;
- use App\Model\Service;
- use App\Model\User;
- use Carbon\Carbon;
- use Illuminate\Support\Collection;
- class SpecialTestSeeder extends DefaultTableSeeder
- {
- // ~ reservations: 20915
- const FROM_YEAR = 2017;
- const FROM_MONTH = 05;
- const CHANCE_OF_NO_PAST_RESERVATION = 70;
- const PAST_RESERVATION_CHANCE_COMPLETED = 40;
- const PAST_RESERVATION_CHANCE_CANCELLED_BY_USER = 20;
- const PAST_RESERVATION_CHANCE_CANCELLED_BY_PROVIDER = 7;
- const PAST_RESERVATION_CHANCE_NOT_SHOW = 30;
- const PAST_RESERVATION_CHANCE_CANCELLED_BY_ADMIN = 3;
- const CHANCE_OF_NO_FUTURE_RESERVATION = 80;
- const FUTURE_RESERVATION_CHANCE_ACTIVE = 80;
- const FUTURE_RESERVATION_CHANCE_CANCELLED_BY_USER = 15;
- const FUTURE_RESERVATION_CHANCE_CANCELLED_BY_PROVIDER = 4;
- const FUTURE_RESERVATION_CHANCE_CANCELLED_BY_ADMIN = 1;
- const NO_CATEGORIES = 2;
- const NO_SERVICES_EACH_CATEGORY = 3;
- const COMPANY_EMAIL = 'system+company@book-a-look-eu.com';
- const USER_PASSWORD = 'drujba_special_secret';
- /** @var Faker\Generator */
- private $faker;
- /**
- * firstName, lastName, imagePrefixPath
- * @var array
- */
- private $providers = [
- 1 => ['Jora', 'Kardan', '1.jpg'],
- 2 => ['Vitea', 'Buric', '2.jpg'],
- 3 => ['Borea', 'Guzgan', '3.png'],
- 4 => ['Hasan', 'Turbatu', '4.jpg'],
- 5 => ['Vova', 'Furculita', '5.jpg'],
- 6 => ['Leonea', 'Jitelu', '6.jpg'],
- 7 => ['Vanea', 'Plaskagupts', '7.jpeg'],
- ];
- /**
- * duration_slots, price, providers
- * @var array
- */
- private $companyServices = [
- 1 => [1, 20.5, [1]],
- 2 => [2, 15.0, [2, 3, 4, 5]],
- 3 => [3, 18.25, [3, 4, 6]],
- 4 => [4, 45.0, [3, 4, 5, 6, 7]],
- 5 => [5, 90.0, [5, 6]],
- 6 => [6, 66.6, [2, 4, 5, 6, 7]],
- ];
- public function __construct()
- {
- $this->faker = Faker\Factory::create('ro');
- $this->faker->seed('2018');
- }
- /**
- * @param boolean $isPassed
- * @return integer
- * @throws SystemException
- */
- private function getRandomReservationStatus($isPassed)
- {
- $chances = $isPassed ? [
- self::PAST_RESERVATION_CHANCE_COMPLETED => Reservation::STATUS_COMPLETED,
- self::PAST_RESERVATION_CHANCE_NOT_SHOW => Reservation::STATUS_NOT_SHOW,
- self::PAST_RESERVATION_CHANCE_CANCELLED_BY_USER => Reservation::STATUS_CANCELLED_BY_USER,
- self::PAST_RESERVATION_CHANCE_CANCELLED_BY_PROVIDER => Reservation::STATUS_CANCELLED_BY_PROVIDER,
- self::PAST_RESERVATION_CHANCE_CANCELLED_BY_ADMIN => Reservation::STATUS_CANCELLED_BY_ADMIN,
- ] : [
- self::FUTURE_RESERVATION_CHANCE_ACTIVE => Reservation::STATUS_ACTIVE,
- self::FUTURE_RESERVATION_CHANCE_CANCELLED_BY_USER => Reservation::STATUS_CANCELLED_BY_USER,
- self::FUTURE_RESERVATION_CHANCE_CANCELLED_BY_PROVIDER => Reservation::STATUS_CANCELLED_BY_PROVIDER,
- self::FUTURE_RESERVATION_CHANCE_CANCELLED_BY_ADMIN => Reservation::STATUS_CANCELLED_BY_ADMIN,
- ];
- $number = $this->faker->numberBetween(1, 100);
- foreach ($chances as $chance => $status) {
- if ($number <= $chance) {
- return $status;
- }
- $number -= $chance;
- }
- throw new SystemException('Incomplete chances (100%)');
- }
- /**
- * @param City $city
- * @return Location
- */
- private function addLocation(City $city)
- {
- return factory(Location::class)->create([
- 'address' => 'Special test address',
- 'city_id' => $city->id,
- 'lat' => '46.7738502',
- 'lng' => '23.6253739',
- ]);
- }
- /**
- * @return User
- */
- private function addCompanyAdminUser()
- {
- return factory(User::class)->create([
- 'email' => self::COMPANY_EMAIL,
- 'first_name' => 'CompanyUser',
- 'last_name' => 'SpecialTest',
- 'password' => self::USER_PASSWORD,
- 'is_password_confirmed' => true,
- 'status' => User::STATUS_ACTIVE,
- 'role' => User::ROLE_COMPANY_ADMIN,
- ]);
- }
- /**
- * @param int $key
- * @return User
- */
- private function addProviderUser($key)
- {
- return factory(User::class)->create([
- 'email' => "system+provider{$key}@book-a-look-eu.com",
- 'first_name' => $this->providers[$key][0],
- 'last_name' => "{$this->providers[$key][1]}{$key}",
- 'password' => self::USER_PASSWORD,
- 'is_password_confirmed' => true,
- 'status' => User::STATUS_ACTIVE,
- 'role' => User::ROLE_PROVIDER,
- ]);
- }
- /**
- * @param int $key
- * @return User
- */
- private function addClientUser($key)
- {
- return factory(User::class)->create([
- 'email' => "system+client{$key}@book-a-look-eu.com",
- 'first_name' => $this->faker->firstName,
- 'last_name' => "{$this->faker->lastName}{$key}",
- 'password' => self::USER_PASSWORD,
- 'is_password_confirmed' => true,
- 'status' => User::STATUS_ACTIVE,
- 'role' => User::ROLE_USER,
- ]);
- }
- /**
- * @return Image
- */
- private function addCompanyImage()
- {
- return Image::create([
- 'path' => 'images/special_test/company.png',
- ]);
- }
- /**
- * @param int $key
- * @return Image
- */
- private function addProviderImage($key)
- {
- $prefix = $this->providers[$key][2];
- return Image::create([
- 'path' => "images/special_test/providers/$prefix",
- ]);
- }
- /**
- * @param Carbon $companyCreated
- * @return Company
- */
- private function addCompany(Carbon $companyCreated)
- {
- $city = City::whereName('Cluj-Napoca')->firstOrFail();
- $location = $this->addLocation($city);
- $companyAdminUser = $this->addCompanyAdminUser();
- $companyImage = $this->addCompanyImage();
- $country = $city->country;
- $currency = $country->currency;
- return factory(Company::class)->create([
- 'name' => 'Book-a-look SpecialTestCompany',
- 'description' => 'This is our special test company',
- 'email' => $companyAdminUser->email,
- 'location_id' => $location->id,
- 'image_id' => $companyImage->id,
- 'setup_step' => Company::SETUP_STEP_FINISHED,
- 'currency_id' => $currency->id,
- 'timezone' => $city->timezone,
- 'active' => true,
- 'max_schedule_days' => 40,
- 'online' => true,
- 'created_at' => $companyCreated,
- ]);
- }
- /**
- * @param Company $company
- * @return CompanyTimetable
- */
- private function addCompanyTimetable(Company $company)
- {
- $timetableData = [
- 'company_id' => $company->id,
- ];
- foreach ([
- 'monday' => [1, '08:00:00', '19:00:00'],
- 'tuesday' => [1, '09:00:00', '21:00:00'],
- 'wednesday' => [0, '06:00:00', '22:00:00'],
- 'thursday' => [1, '07:00:00', '16:00:00'],
- 'friday' => [1, '11:00:00', '15:00:00'],
- ] as $day => $data) {
- $timetableData += [
- "{$day}_enabled" => $data[0],
- "{$day}_start" => $data[1],
- "{$day}_end" => $data[2],
- ];
- }
- return CompanyTimetable::create($timetableData);
- }
- /**
- * @param Company $company
- * @param int $key
- * @return Provider
- */
- private function addProvider(Company $company, $key)
- {
- $user = $this->addProviderUser($key);
- $image = $this->addProviderImage($key);
- return factory(Provider::class)->create([
- 'user_id' => $user->id,
- 'company_id' => $company->id,
- 'image_id' => $image->id,
- ]);
- }
- /**
- * @param int $key
- * @return Category
- */
- private function addCategory($key)
- {
- return factory(Category::class)->create([
- 'name' => "SpecialTest Category {$key}",
- ]);
- }
- /**
- * @param Category $category
- * @param int $key
- * @return Service
- */
- private function addService(Category $category, $key)
- {
- return factory(Service::class)->create([
- 'category_id' => $category->id,
- 'name' => "SpecialTest Service {$key}",
- 'active' => true,
- ]);
- }
- /**
- * @param Company $company
- * @param Service service
- * @param int $key
- * @return CompanyService
- */
- private function addCompanyService(Company $company, Service $service, $key)
- {
- return factory(CompanyService::class)->create([
- 'company_id' => $company->id,
- 'service_id' => $service->id,
- 'duration_slots' => $this->companyServices[$key][0],
- 'price' => $this->companyServices[$key][1],
- ]);
- }
- /**
- * @param Company $company
- * @param Service $service
- * @param Provider $provider
- * @return CompanyService
- */
- private function addProviderService(Company $company, Service $service, Provider $provider)
- {
- return factory(ProviderService::class)->create([
- 'company_id' => $company->id,
- 'service_id' => $service->id,
- 'provider_id' => $provider->id,
- ]);
- }
- /**
- * @param Company $company
- * @return Collection
- */
- private function addProviders(Company $company)
- {
- $providers = collect();
- foreach (range(1, 7) as $i) {
- $provider = $this->addProvider($company, $i);
- $providers->put($i, $provider);
- }
- return $providers;
- }
- /**
- * @param Company $company
- * @param Collection $providers
- * @return Collection
- */
- private function addProviderServices(Company $company, Collection $providers)
- {
- $providerServicesAndCompanyServices = collect();
- foreach (range(1, self::NO_CATEGORIES) as $i) {
- $category = $this->addCategory($i);
- foreach (range(1, $noServices = self::NO_SERVICES_EACH_CATEGORY) as $j) {
- $key = $noServices * ($i - 1) + $j;
- $service = $this->addService($category, $key);
- $providerServiceAndCompanyService = collect();
- $companyService = $this->addCompanyService($company, $service, $key);
- $providerServiceAndCompanyService->put('companyService', $companyService);
- foreach ($this->companyServices[$key][2] as $providerKey) {
- $provider = $providers->get($providerKey);
- $providerService = $this->addProviderService($company, $service, $provider);
- $providerServiceAndCompanyService->put('providerService', $providerService);
- $providerServicesAndCompanyServices->push($providerServiceAndCompanyService);
- }
- }
- }
- return $providerServicesAndCompanyServices;
- }
- /**
- * @return Collection
- */
- private function addClients()
- {
- $clients = collect();
- collect(range(1, 100))->each(function ($index) use ($clients) {
- $user = $this->addClientUser($index);
- $clients->put($index, $user);
- });
- return $clients;
- }
- /**
- * @param CompanyTimetable $timetable
- * @param Carbon $date
- * @return array|null
- */
- private function getCompanyTimetableStartAndEnd(CompanyTimetable $timetable, Carbon $date)
- {
- foreach ([
- Carbon::MONDAY => CompanyTimetable::MONDAY,
- Carbon::TUESDAY => CompanyTimetable::TUESDAY,
- Carbon::WEDNESDAY => CompanyTimetable::WEDNESDAY,
- Carbon::THURSDAY => CompanyTimetable::THURSDAY,
- Carbon::FRIDAY => CompanyTimetable::FRIDAY,
- Carbon::SATURDAY => CompanyTimetable::SATURDAY,
- Carbon::SUNDAY => CompanyTimetable::SUNDAY,
- ] as $carbonDayOfWeek => $timetableDayOfWeek) {
- if ($date->dayOfWeek !== $carbonDayOfWeek) {
- continue;
- }
- if (!$timetable->isEnabled($timetableDayOfWeek)) {
- return null;
- }
- return [
- $timetable->getStartDateOf($timetableDayOfWeek),
- $timetable->getEndDateOf($timetableDayOfWeek),
- ];
- }
- }
- /**
- * @param Collection $providerServices
- * @param Collection $clients
- * @param CompanyTimetable $companyTimetable
- * @param Carbon $companyCreated
- * @return Collection
- */
- private function addReservations(
- Collection $providerServicesAndCompanyServices,
- Collection $clients,
- CompanyTimetable $companyTimetable,
- Carbon $companyCreated
- ) {
- $reservations = collect();
- $oneSlotInMinutes = config('schedules.one_slot_in_minutes');
- $maxScheduleDays = $companyTimetable->company->max_schedule_days;
- $now = Carbon::now();
- $futureMax = Carbon::now()->addDays($maxScheduleDays);
- $providerServicesAndCompanyServices->each(
- function (Collection $providerServiceAndCompanyService) use (
- $companyTimetable,
- $clients,
- $companyCreated,
- $oneSlotInMinutes,
- $reservations,
- $futureMax,
- $now
- ) {
- /** @var ProviderService $providerService */
- $providerService = $providerServiceAndCompanyService->get('providerService');
- /** @var CompanyService $companyService */
- $companyService = $providerServiceAndCompanyService->get('companyService');
- $durationSlots = $companyService->duration_slots;
- $durationMinutes = $durationSlots * $oneSlotInMinutes;
- $date = $companyCreated->copy()->subDay();
- while ($date < $futureMax) {
- $isPassed = $date < $now;
- $date->addDay();
- if (!$startAndEndTime = $this->getCompanyTimetableStartAndEnd($companyTimetable, $date)) {
- continue;
- }
- list($startTime, $endTime) = $startAndEndTime;
- $time = $date->copy()->setTimeFromTimeString($startTime);
- $lastTime = $date->copy()->setTimeFromTimeString($endTime)->subMinutes($durationMinutes);
- while ($time < $lastTime) {
- $noReservation = $this->faker->boolean(
- $isPassed
- ? self::CHANCE_OF_NO_PAST_RESERVATION
- : self::CHANCE_OF_NO_FUTURE_RESERVATION
- );
- if ($noReservation) {
- $time->addMinutes($oneSlotInMinutes);
- continue;
- }
- $client = $this->faker->randomElement($clients->all());
- $reservation = Reservation::query()->forceCreate([
- 'reserved_at' => $time,
- 'provider_service_id' => $providerService->id,
- 'client_id' => $client->id,
- 'by_user_id' => $client->id,
- 'provider_id' => $providerService->provider_id,
- 'service_id' => $providerService->service_id,
- 'status' => $this->getRandomReservationStatus($isPassed),
- 'company_id' => $providerService->company_id,
- 'price' => $companyService->price,
- 'duration_slots' => $companyService->duration_slots,
- ]);
- $reservations->push($reservation);
- $time->addMinutes($durationMinutes);
- }
- }
- });
- return $reservations;
- }
- private function addSchedules()
- {
- Artisan::call('new-provider:schedules');
- }
- /**
- * @param string $email
- * @return int
- */
- private function deleteExistingCompany($email)
- {
- return Company::whereEmail($email)->delete();
- }
- /**
- * @param string $email
- * @return int
- */
- private function deleteExistingUser($email)
- {
- return User::whereEmail($email)->delete();
- }
- public function testRun()
- {
- $this->deleteExistingCompany(self::COMPANY_EMAIL);
- $this->deleteExistingUser(self::COMPANY_EMAIL);
- $companyCreated = Carbon::createFromDate(self::FROM_YEAR,self::FROM_MONTH)->firstOfMonth();
- $company = $this->addCompany($companyCreated);
- $companyTimetable = $this->addCompanyTimetable($company);
- $providers = $this->addProviders($company);
- // $this->addSchedules();
- $providerServicesAndCompanyServices = $this->addProviderServices($company, $providers);
- $clients = $this->addClients();
- $this->addReservations($providerServicesAndCompanyServices, $clients, $companyTimetable, $companyCreated);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement